问题遇到的现象和发生背景
多线程异步处理图片报内存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,但添加内存并不能解决问题