1

我提出了一個新問題,因爲這與我的最後一個線程不同。我現在知道這個問題更準確。Java BufferedArrayOutputStream在內存中泄漏

我創建了一個新的bytearrayoutputstream

ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); 

沒什麼特別的。 然後,當我寫的圖像給它,這樣

ImageIO.write(image, "gif", byteArray); 

內存增加,如100 MB首先,不要在日食,但在「現實」。然後,在每次我向該流或另一個流寫入新圖像時,它會慢慢增加!

經過一段時間它停止工作,有點崩潰。

我已經嘗試關閉它,所有的,沖洗,重置,一切,但它仍然泄漏內存。當我停止使用byteArray或將它清空時,我希望它遠離內存。

System.gc(); 

不會幫助在這種情況下。

請幫我和其他任何你需要知道我要回答,請返回並回信:)

+0

在這種情況下,您不需要手動調用'System.gc()'。如果你關閉了所有未使用的資源/流/等,那麼你應該沒問題。嘗試增加對Java內存的限制 – nevets1219 2012-08-14 17:58:57

+2

YOu應包含更多代碼 – leonbloy 2012-08-14 18:00:05

+0

我同意。你可能在未顯示的代碼中做錯了事。 – 2012-08-14 18:10:23

回答

0

你的使用模式應該是這樣的:

while(keepRunning) { 
    ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); 
    ImageIO.write(image, "gif", byteArray); 
} 

如果你這樣做快於JVM可以收集垃圾,最終會得到非常長的GC暫停或OutOfMemory異常。

+0

nope。沒那麼快。也許一次我做那個。但之後,我關閉它。 – 2012-08-14 17:59:48

+0

無論如何,我可以使用相同的bytearrayoutputstream並每次使用它的數據重置它? – 2012-08-14 18:01:05

+0

你現在重置嗎?重置不會擺脫已分配的任何現有內存,但會覆蓋現有的基礎byte []緩衝區。 – Dave 2012-08-14 18:10:42

0

你有沒有嘗試過這樣的:

try{ 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ImageIO.write(image, "png", baos); 
    baos.flush(); 
    byte[] imageBytes = baos.toByteArray(); 
    baos.close(); 
}catch(Exception ex){ 
    System.out.println(ex.getMessage()); 
} 
+0

也一樣。仍然在內存中結束 – 2012-08-14 18:39:06

0

你在做什麼並沒有任何意義。您將圖像從內存中取出並重新放入內存,這次是字節數組。

您應該將該圖像放入文件或通過網絡發送。或者,如果您只想保留副本,請複製圖像(不是字節陣列!),如我在此處所述:Bug in using Object.clone()

0

請參閱similar answer I posted to another ByteArrayOutputStream question

ByteArrayOutputStream中沒有允許您縮小緩衝區的方法。重置更改緩衝區中的位置。

爲您的解決方案是

  1. 使用構造使用前指定緩衝區的大小。當您將大對象寫入流時,這將節省大量內存並防止出現OOM異常。
  2. 如果您想重新使用您的BAOS對象,請致電重置。這將使下一次寫入開始於緩衝區的開始處。
  3. 釋放內存的唯一方法是刪除對它的所有引用。在上面的代碼中,你會說byteArray = null;