执行javax.imageio.imageio.read(“文件名”)时发生java.lang.OutOfMemoryError

执行javax.imageio.imageio.read(“文件名”)时发生java.lang.OutOfMemoryError,java,eclipse,image,Java,Eclipse,Image,我想压缩“JPG”图像,大约400万张或更多。以下是我的代码: public static void Compress(String sourceFolder,String destFolder,double proportion) throws IOException { File source=new File(sourceFolder); File[] sourceFiles=null; if(source.isDirectory()) {

我想压缩“JPG”图像,大约400万张或更多。以下是我的代码:

public static void Compress(String sourceFolder,String destFolder,double proportion) throws IOException
{
    File source=new File(sourceFolder);
    File[] sourceFiles=null;
    if(source.isDirectory())
    {
        sourceFiles=source.listFiles();
        for(int i=0;i<sourceFiles.length;i++)
        {
            String name="";
            javax.imageio.ImageIO.setUseCache(false);
            Image src = javax.imageio.ImageIO.read(sourceFiles[i]);
            name=sourceFiles[i].getName();
            int width=src.getWidth(null);
            int height=src.getHeight(null);
            destWidth=(int) (height*proportion);
            destHeight=(int) (width*proportion);
            BufferedImage tag=new BufferedImage(destWidth,destHeight,BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();  
            g.drawImage(src, 0, 0, destWidth, destHeight, null);
            src.flush();
            src=null;
            FileOutputStream out = new FileOutputStream(destFolder+"/"+name);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
            encoder.encode(tag);  
            out.close(); 
        }
    }
    else
        System.exit(0);
}
发生异常:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:58)
at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397)
at java.awt.image.Raster.createWritableRaster(Raster.java:938)
at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056)
at javax.imageio.ImageReader.getDestination(ImageReader.java:2879)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:943)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:915)
at javax.imageio.ImageIO.read(ImageIO.java:1422)
at javax.imageio.ImageIO.read(ImageIO.java:1282)
at functions.CompressImage.Compress(CompressImage.java:50)
at functions.CompressImage.main(CompressImage.java:24)
线程“main”java.lang.OutOfMemoryError中的异常:java堆空间 位于java.awt.image.DataBufferByte。(DataBufferByte.java:58) 位于java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397) 位于java.awt.image.Raster.createWritableRaster(Raster.java:938) 在javax.imageio.ImageTypeSpecifier.createBuffereImage(ImageTypeSpecifier.java:1056) 位于javax.imageio.ImageReader.getDestination(ImageReader.java:2879) 位于com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:943) 位于com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:915) 在javax.imageio.imageio.read(imageio.java:1422) 在javax.imageio.imageio.read(imageio.java:1282) 压缩(CompressImage.java:50) 位于functions.CompressImage.main(CompressImage.java:24) 我尝试了运行参数(-Xms=1g),但仍然不起作用!
谁知道解决办法?请帮帮我,谢谢

您需要获取堆转储并对其进行分析。因此,最简单的方法是添加JVM参数,如

 -XX:+HeapDumpOnOutOfMemoryError 

这将自动创建堆转储/稍后您可以使用java探查器(yourkit、jprofiler等)分析错误。

4MB JPG将生成一个巨大的位图文件。我想,它只需要大量的内存。我经常在javax.imagio中读到关于大内存消耗的文章

要获得位图大小,请计算image_X*image_Y*(8到10位*3(颜色))

更新 一些数学:

我假设每个颜色通道8比特:

7000*4900*8*3=1029000000位 =122MB


我知道,内存中必须有122MB的字节[]。如果操作系统(而不是JVM)无法创建该内存块,则会出现该异常。

是否尝试设置-Xmx(最大堆大小)?有多少个映像?或者总共4MB?请注意,如果Xmx小于-Xmx,那么-Xms=1g没有帮助,其次语法是-xmx1g,没有分号或“=”。您是否可以尝试只读取一个文件而不执行任何操作,以查看是否再次引发异常。并确保文件夹中除了图像之外没有任何子文件夹和文件。应用程序是否生成了堆转储?关键是JVM将自动为您创建堆转储-通常在JVM启动的同一目录中。有关详细信息,请阅读本博客。您应该有如下内容:java-XX:+heapdumponautofmemoryerror-mn256m-mx512m consumerheap java.lang.OutOfMemoryError:java堆空间转储堆到java_pid2262.hprof。。。堆转储文件在线程“main”java.lang.OutOfMemoryError中创建[531535128字节(14.691秒)]异常:ConsumerHeap$BigObject处的java堆空间。(ConsumerHeap.java:22)ConsumerHeap.main(ConsumerHeap.java:32)$图像的分辨率约为4900*7000
 -XX:+HeapDumpOnOutOfMemoryError