Java 我在读取图像时出现OutOfMemory错误

Java 我在读取图像时出现OutOfMemory错误,java,jar,inputstream,out-of-memory,javax.imageio,Java,Jar,Inputstream,Out Of Memory,Javax.imageio,好的,我正在读取.jar文件中名为“images”的子目录中的图像,当然我必须通过流访问它们,因为它位于.jar中。以下是读取图像的内容: private Image wPawn = getImage(getClass().getResourceAsStream("images/WhitePawn.png")), bPawn = getImage(getClass().getResourceAsStream("images/BlackPawn.png")),

好的,我正在读取.jar文件中名为“images”的子目录中的图像,当然我必须通过流访问它们,因为它位于.jar中。以下是读取图像的内容:

    private Image wPawn = getImage(getClass().getResourceAsStream("images/WhitePawn.png")),
        bPawn = getImage(getClass().getResourceAsStream("images/BlackPawn.png")),
        wRook = getImage(getClass().getResourceAsStream("images/WhiteRook.png")),
        bRook = getImage(getClass().getResourceAsStream("images/BlackRook.png")),
        wKnight = getImage(getClass().getResourceAsStream("images/WhiteKnight.png")),
        bKnight = getImage(getClass().getResourceAsStream("images/BlackKnight.png")),
        wBishop = getImage(getClass().getResourceAsStream("images/WhiteBishop.png")),
        bBishop = getImage(getClass().getResourceAsStream("images/BlackBishop.png")),
        wQueen = getImage(getClass().getResourceAsStream("images/WhiteQueen.png")),
        bQueen = getImage(getClass().getResourceAsStream("images/BlackQueen.png")),
        wKing = getImage(getClass().getResourceAsStream("images/WhiteKing.png")),
        bKing = getImage(getClass().getResourceAsStream("images/BlackKing.png"));
private Image getImage(InputStream stream){
    Image i;
    try{
        i = ImageIO.read(stream);
        stream.close();
    } catch (IOException e) {
        i = null;
    }
    return i;
}
这段代码可以工作,但运行的国际象棋游戏在我的鼠标输入下落后了很多。以前,我有一个单独的小类做同样的工作,但它并没有导致OutOfMemoryError

错误来自
i=ImageIO.read(流)的行;

并从图像声明中调用它。有人能帮你找出解决这个错误的最佳方法吗?

如果你知道你必须做大量的IO(即,读取一大堆图像),你总是可以增加java应用程序消耗的总堆

这样做的示例如下所示:

java-Xms128m-Xmx256m您的类名在这里


在问题上投入更多的资源永远不是解决方案,除非你知道没有办法解决它。在您优化了解决方案并确保没有内存被浪费,并且应用程序确实需要使用额外的内存之后,我将使用此解决方案作为最后手段

优化/调整/压缩图像。12个PNG代表游戏中使用的大小的简单棋子不可能占用足够的内存,即使堆大小为32M或64M。

诊断OOM的最佳方法是使用探查器。非常好,我相信它有一个免费试用期

此外,请记住,OOM通常是误导性的。仅仅因为OOM被抛出到一个特定的行,并不意味着这是一个占用大量内存的行;这只是使用了最后一位可用内存的行。例如:

byte[] unused = new byte[availableMemory - 1];
byte[] reallyImportant = new byte[10]; // throws OutOfMemoryError
Image.read()
将图像数据缓存在内存/磁盘中


我回答了一个类似的问题

问题不在于文件大小,正如我在前面提到的,这些部分使用单独的类。我的PNG是带有透明背景的150x150双色PNG。它可能与图像完全无关,但我的下一个猜测是,您正在重复加载图像,而不是加载一次并缓存它们以备将来使用。否则,您将需要进行一些内存分析,以找出哪些对象占用了所有空间。这是一个有点晚的响应,但我只加载PNG一次,并将其保存为图像(实际上是缓冲区图像,这是ImageIO提供给您的,但我只将它们作为图像读取)。这些图像经常被调用,但实际上只被读取一次。此外,由于我不熟悉如何为每个单独的类管理内存,单独的类是否会有一个ChessPiece类从未接触过的单独分配内存储备,或者每个类的内存都是同一堆的一部分?@Cameron问题不在于文件大小,正如我前面提到的处理单独类的部分。我的PNG是带有透明背景的150x150双色PNG。总是很难诊断OutOfMemoryErrors,所以你需要你能得到的所有信息。在早期排除图像大小很重要,所以这就是我问的原因。除非你的PNG文件太大(解码图像尺寸,而不是文件大小),否则问题不大可能在你发布的代码中显示出来。这更像是在你开始加载图标之前,其他东西会吃掉所有的内存,或者你会多次加载图标。请记住,
OutOfMemoryError
只会告诉您JVM在内存耗尽时正在做什么。问:有人能帮我找出解决这个错误的最佳方法吗?答:使用内存分析器。分配的内存不应该是问题所在,因为当我使用单独的类通过ImageIO获取图像时,应用程序工作正常,没有延迟。