2011-12-08

Tags: 程式語言 , java

有一定程度的java programmer應該都知道,雖然java沒有C的pointer,但是程式沒寫好還是會導致memory leak。跟C的memory leak不同之處在於,C是沒把locate的memory還給OS,java的memory leak則是無用的變數(或是該被GC的變數沒被GC)一直佔用memory,直到jvm消滅時才一口氣把memory還給OS。

java memory leak的一整個前因後果可參照下面這篇文章
How to Fix Memory Leaks in Java

要去追查java memory leak的方法有很多,stackoverflow 有篇文章蠻完整的,可供參考。簡單來說,追的流程如下

  1. 程式啟動時加入下面這類的參數,讓它在jvm炸掉時自動dump heap
    -Xmx64m -XX:+HeapDumpOnOutOfMemoryError
  2. 如果是想在程式執行時手動dump heap則是經由jmap指令、jconsole工具、或是Eclipse Memory Analyzer這個plugin
  3. 有了倒出來的heap後,就可以用jhat指令或是Eclipse Memory Analyzer來分析到底程式是哪裡出包,導致leak產生。 
操作Eclipse Memory Analyzer來追leak,可以參考下面儿篇文章。
使用 Eclipse Memory Analyzer 檢測內存洩漏問題
使用Memory Analyzer tool(MAT)分析內存洩漏(一)
使用Memory Analyzer tool(MAT)分析內存洩漏(二)

我自己通常是在Leak Hunter報表產生後,就依其內容去追leak原因。通常這樣就抓的到哪裡用了最多的memory,找到兇手。不過...有時會發現...其實你的程式就是要吃這麼多memory,你的List或Map object裡就是要放巨量的資料,根本不是啥memory leak。這時就只好放大jvm的max heap size,不然就是硬體加RAM才能解了(內心OS:這就是人蔘呀~~)。