2011-08-06 23 views
2

好吧,我正在讀取名爲'images'的.jar文件的子目錄中的圖像,當然,我必須通過流訪問它們,因爲它位於.jar中。這是讀取圖片:我在閱讀圖片時遇到OutOfMemory錯誤

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(stream); 的行,它從圖像聲明中調用。任何人都可以幫助找出最好的方法來糾正錯誤?

+0

圖像有多大? –

+0

@Cameron問題不在於文件大小,正如我之前提到的那些與獨立類一起工作的文件。我的PNG是150x150具有透明背景的2色PNG。 –

+0

診斷OutOfMemoryErrors總是很難,因此您需要獲取所有信息。儘早排除圖像的大小很重要,所以我就問這個問題。 –

回答

0

如果您知道必須執行大量的IO(即讀取大量圖像),則始終可以增加Java應用程序消耗的總堆量。

一個例子來做到這一點應該是這樣的:

的java -Xms128m -Xmx256m YourClassNameHere

在問題投入更多的資源從來都不是解決辦法,除非你知道,有沒有辦法周圍。在優化解決方案並確保沒有內存被浪費並且應用程序確實需要使用額外內存之後,我會使用此解決方案作爲最後的手段。

+0

分配的內存不應該成爲問題,因爲當我使用單獨的類通過ImageIO獲取圖像時,應用程序工作得很好,沒有滯後。 –

1

優化/調整/壓縮您的圖像。在遊戲中使用大小不等的十二個PNG代表簡單的棋子應該佔用足夠的空間來運行你的內存,即使在32M或64M堆大小。

+0

問題不在於文件大小,正如我之前提到的與單獨的類一起使用的部分。我的PNG是150x150具有透明背景的2色PNG。 –

+0

它可能完全不相關的圖像,但我的下一個猜測是,你反覆加載圖像,而不是加載一次,並緩存它們以備將來使用。否則,你會想要做一些內存分析來找出哪些對象佔用了所有的空間。 –

+0

這是一個響應有點晚,但我只加載一次PNG,並將它們保存爲圖像(實際上是BufferedImages,因爲這是ImageIO給你的,但我只讀它們作爲圖像)。這些圖像經常被調用,但它們只被實際讀取一次。 –

0

診斷OOM的最佳方法是使用分析器。 JProfiler非常好,我相信它有一個免費試用期。

另外,請記住,OOM往往是誤導。僅僅因爲OOM被拋在一個特定的線上並不意味着這是使用大量內存的線;它只是使用最後位的可用內存。例如:

byte[] unused = new byte[availableMemory - 1]; 
byte[] reallyImportant = new byte[10]; // throws OutOfMemoryError 
0
Image.read() caches the image data in memory/disk. 

已經回答過類似的問題。 Please Check here