GYBYPtree 2023-01-05 11:12 采纳率: 50%
浏览 77

多线程异步处理多张图片报内存java.lang.OutOfMemoryError: Java heap space异常

问题遇到的现象和发生背景

多线程异步处理图片报内存java.lang.OutOfMemoryError: Java heap space异常

遇到的现象和发生背景,请写出第一个错误信息

项目需要一次对几十张图片进行处理,包含图片压缩、图片合并、给图片添加文字,如果一张一张的处理速度会非常慢,而我使用多线程在for循环中处理图片又会报内存不足抛出Exception in thread "pool-3-thread-1" java.lang.OutOfMemoryError: Java heap space,请教如何解决呢,以下贴出压缩图片业务实例

用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%

压缩图片的主要业务代码

int nThread=20;
CountDownLatch latch=new CountDownLatch(list.size());
ExecutorService executorService = Executors.newFixedThreadPool(nThread);// 创建一个固定的线程池
for (BizContractAttach designImg : list) {       //图片
    executorService.execute(() -> {
        // 此处可以放入待处理的业务
        try {
            String imgName;
            String imgExt;
            String copyPath;
            String imgPath = designImg.getPath();
            int status = 0;
            if (type == 1) {
                if (StringUtils.isNotBlank(designImg.getPathII()) && contract.getOrderStatus().equals("已作废")) {
                    imgPath = designImg.getPathII();
                    status=2;
                } else if (StringUtils.isNotBlank(designImg.getCopyPath())
                        && contract.getStatus().equals("已签约")) {
                    imgPath = designImg.getCopyPath();
                    status=1;
                }
            }
            imgPath = new String(Base64Utils.decodeFromString(imgPath), "UTF-8");
            imgName = imgPath.substring(0, imgPath.lastIndexOf('.'));
            imgExt = imgPath.substring(imgPath.lastIndexOf('.'));
            copyPath = imgName + "CPS" + imgExt;
            if (PdfUtil.isImage(imgExt)) {
                                 //压缩图片
                File outFile=ImageUtils.compressImage(imgPath, copyPath, null); 
                if(outFile!=null) {
                    designImg.setSize(PdfUtil.getFileSize(outFile.length()));
                    if(status==0) {
                        designImg.setPath(copyPath);
                    }else if(status==2) {
                        designImg.setPathII(copyPath);
                    }else if(status==1) {
                        designImg.setCopyPath(copyPath);
                    }
                }
            }
            latch.countDown();
        } catch (Exception e) {
            // TODO: handle exception
            log.error("图纸压缩失败", e);
            e.printStackTrace();
        }
    });
}
latch.await();
executorService.shutdown();
JpaUtil.merge(list);

图片压缩的工具方法

public static File compressImage(File input, File outFile, long size) throws IOException {
        FileOutputStream outputStream=new FileOutputStream(outFile);
        BufferedImage bufferedImage=ImageIO.read(input);
        int width=bufferedImage.getWidth();
        float scale=0.5f;
        float quality=0.5f;
        if(width>=10000) {
            scale=0.15f;
        }else if(width>=7000&&width<10000) {
            scale=0.2f;
        }else if (width>=5000&&width<7000) {
            scale=0.3f;
        }else if (width>2000&&width<5000) {
            scale=0.6f;
        }
        long base=1048576;
        if(size>=base*7) {
            quality=0.3f;
        }else if(size>=base*5&&size<base*7) {
            quality=0.4f;
        }else if(size>base*2&&size<base*5) {
            quality=0.8f;
        }
        Thumbnails.of(input)
                .scale(scale) //图片大小(长宽)压缩比例 从0-1,1表示原图
                .outputQuality(quality) //图片质量压缩比例 从0-1,越接近1质量越好
                    .toOutputStream(outputStream);
        outputStream.close();
        return outFile;
}

运行结果及详细报错内容

报错信息,本地测试三张图片

Exception in thread "pool-3-thread-1" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92)
    at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:445)
    at java.awt.image.Raster.createWritableRaster(Raster.java:941)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1074)
    at javax.imageio.ImageReader.getDestination(ImageReader.java:2892)
    at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1317)
    at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1614)
    at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.readImage(Unknown Source)
    at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.read(Unknown Source)
    at net.coobird.thumbnailator.tasks.io.FileImageSource.read(Unknown Source)
    at net.coobird.thumbnailator.tasks.SourceSinkThumbnailTask.read(Unknown Source)
    at net.coobird.thumbnailator.Thumbnailator.createThumbnail(Unknown Source)
    at net.coobird.thumbnailator.Thumbnails$Builder.toOutputStream(Unknown Source)
    at com.cqjysoft.cqjyxdzs.common.utils.ImageUtils.compressImage(ImageUtils.java:150)
    at com.cqjysoft.cqjyxdzs.common.utils.ImageUtils.compressImage(ImageUtils.java:117)
    at com.cqjysoft.cqjyxdzs.bizcontract.service.BizAsyncService.lambda$2(BizAsyncService.java:230)
    at com.cqjysoft.cqjyxdzs.bizcontract.service.BizAsyncService$$Lambda$627/1367920516.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
Exception in thread "pool-3-thread-3" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92)
    at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:445)
    at java.awt.image.Raster.createWritableRaster(Raster.java:941)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1074)
    at javax.imageio.ImageReader.getDestination(ImageReader.java:2892)
    at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1317)
    at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1614)
    at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.readImage(Unknown Source)
    at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.read(Unknown Source)
    at net.coobird.thumbnailator.tasks.io.FileImageSource.read(Unknown Source)
    at net.coobird.thumbnailator.tasks.SourceSinkThumbnailTask.read(Unknown Source)
    at net.coobird.thumbnailator.Thumbnailator.createThumbnail(Unknown Source)
    at net.coobird.thumbnailator.Thumbnails$Builder.toOutputStream(Unknown Source)
    at com.cqjysoft.cqjyxdzs.common.utils.ImageUtils.compressImage(ImageUtils.java:150)
    at com.cqjysoft.cqjyxdzs.common.utils.ImageUtils.compressImage(ImageUtils.java:117)
    at com.cqjysoft.cqjyxdzs.bizcontract.service.BizAsyncService.lambda$2(BizAsyncService.java:230)
    at com.cqjysoft.cqjyxdzs.bizcontract.service.BizAsyncService$$Lambda$627/1367920516.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
Exception in thread "pool-3-thread-2" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92)
    at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:445)
    at java.awt.image.Raster.createWritableRaster(Raster.java:941)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1074)
    at javax.imageio.ImageReader.getDestination(ImageReader.java:2892)
    at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1317)
    at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1614)
    at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.readImage(Unknown Source)
    at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.read(Unknown Source)
    at net.coobird.thumbnailator.tasks.io.FileImageSource.read(Unknown Source)
    at net.coobird.thumbnailator.tasks.SourceSinkThumbnailTask.read(Unknown Source)
    at net.coobird.thumbnailator.Thumbnailator.createThumbnail(Unknown Source)
    at net.coobird.thumbnailator.Thumbnails$Builder.toOutputStream(Unknown Source)
    at com.cqjysoft.cqjyxdzs.common.utils.ImageUtils.compressImage(ImageUtils.java:150)
    at com.cqjysoft.cqjyxdzs.common.utils.ImageUtils.compressImage(ImageUtils.java:117)
    at com.cqjysoft.cqjyxdzs.bizcontract.service.BizAsyncService.lambda$2(BizAsyncService.java:230)
    at com.cqjysoft.cqjyxdzs.bizcontract.service.BizAsyncService$$Lambda$627/1367920516.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)

我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%

我已经把在eclipse中jdk的参数改成了-Xms512m -Xmx2048m,但添加内存并不能解决问题

我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”
  • 写回答

4条回答 默认 最新

  • 於黾 2023-01-05 11:24
    关注

    就算一个图片5M,几十张图片也不应该内存溢出啊,应该是你声明的image对象没有释放导致内存泄漏

    评论

报告相同问题?

问题事件

  • 创建了问题 1月5日

悬赏问题

  • ¥15 Opencv(C++)异常
  • ¥15 VScode上配置C语言环境
  • ¥15 汇编语言没有主程序吗?
  • ¥15 这个函数为什么会爆内存
  • ¥15 无法装系统,grub成了顽固拦路虎
  • ¥15 springboot aop 应用启动异常
  • ¥15 matlab有关债券凸性久期的代码
  • ¥15 lvgl v8.2定时器提前到来
  • ¥15 qtcp 发送数据时偶尔会遇到发送数据失败?用的MSVC编译器(标签-qt|关键词-tcp)
  • ¥15 cam_lidar_calibration报错