繁体   English   中英

当我加载大约40mb大小的11k图像时,为什么会出现java堆空间异常

[英]Why do I get a java heap space exception when I load around 11k images with a size of around 40mb

我的程序中有一种情况,我需要访问保存在硬盘上的一定数量的图像。 我可以只在我真正需要它们时加载它们,或者在启动时加载它们。

出于好奇,我试图从几个文件夹中读取所有(大约11k)图像,并将它们保存在多个列表中。 我想知道这是否需要太长时间,但在阅读约9k图像后收到OutOfMemoryError。

我的JRE的堆大小为1g(-Xmx1g)。

为什么我的代码会发生这种情况? 我是否会产生内存泄漏? 你有什么建议可以改变,因为没有经历过这个或者解决方案只是为了只阅读文件,一旦我需要它们? 所有文件的整体大小只有40mb左右,所以我认为将它保存在我的内存中是可以的(40mb似乎与我的1g堆大小不太一样)。 或者java执行一些疯狂的魔法东西,一旦加载文件大小乘以高数字?

我已经对stackoverflow做了一些研究,但是对于我的情况,无法真正转换给定的答案(比如从这里这里 )。 所以,如果你们中有人有想法,我会非常高兴:)

我的代码在这里,对不起,如果它有点难看 - 我只是搞乱了:

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

public class FatfontsManager {

    private List<BufferedImage> until9;
    private List<BufferedImage> until99;
    private List<BufferedImage> until999;
    private List<BufferedImage> until9999;

    // loads and keeps all images 

    public FatfontsManager() {

        until9 = new ArrayList<>();
        until99 = new ArrayList<>();
        until999 = new ArrayList<>();
        until9999 = new ArrayList<>();

        String absolutPathToThisProject = new java.io.File("")
                .getAbsolutePath();

        // load Images
        for (int i = 1; i < 10; i++) {
            until9.add(loadImage(absolutPathToThisProject
                    + "\\latexDir\\0..9\\" + i + ".png"));
        }
        System.out.println("1 - 9 loaded");
        for (int i = 1; i < 100; i++) {
            until99.add(loadImage(absolutPathToThisProject
                    + "\\latexDir\\0..99\\" + i + ".png"));
        }
        System.out.println("1 - 99 loaded");
        for (int i = 1; i < 1000; i++) {
            until999.add(loadImage(absolutPathToThisProject
                    + "\\latexDir\\0..999\\" + i + ".png"));
        }
        System.out.println("1 - 999 loaded");
        for (int i = 1; i < 10000; i++) {
            until9999.add(loadImage(absolutPathToThisProject
                    + "\\latexDir\\0..9999\\" + i + ".png"));
        }
        System.out.println("1 - 9999 loaded");
    }

    public static void main(String[] args) {
        new FatfontsManager();
    }

    public static BufferedImage loadImage(String ref) {
        BufferedImage bimg = null;
        try {

            bimg = ImageIO.read(new File(ref));
        } catch (Exception e) {
            System.err.println("Error loading image file " + ref);
            e.printStackTrace();
        }
        return bimg;
    }

}

非常感谢每一个答案。

所有文件的总体大小只有40mb左右......

但是当您将图像文件加载到内存中时,图像将解压缩并转换为像素数组。 根据原始图像文件格式(和压缩参数),这可能需要一个数量级或更多的堆空间。

你想要实现的目标并不完全清楚,但也许你应该考虑只在实际使用时将这些图像缓存在内存中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM