Java でメモリ リークを示すサンプル プログラムを作成します。
public class MemoryLeakTest {
static int depth = 0;
int number=0;
MemoryLeakTest mobj;
MemoryLeakTest(){
number = depth;
if(depth < 6500){
depth++;
mobj = new MemoryLeakTest();
}
}
protected void finalize(){
System.out.println(number + " released.");
}
public static void main(String[] args) {
try{
System.out.println(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());
System.out.println("Free Memory in starting "+ Runtime.getRuntime().freeMemory());
MemoryLeakTest testObj = new MemoryLeakTest();
System.out.println("Free Memory in end "+ Runtime.getRuntime().freeMemory());
System.out.println(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());
}
catch(Exception exp){}
finally{
System.out.println("Free Memory"+ Runtime.getRuntime().freeMemory());
System.out.println(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());
}
}
}
N in の値を変更して実行しif(depth < N)
ます。ここに結果があります。
深さが1000の場合
init = 16777216(16384K) used = 288808(282K) commit = 16252928(15872K) max = 259522560(253440K) 15872K) 最大 = 259522560(253440K) 空きメモリ 15964120 初期化 = 16777216(16384K) 使用済み = 288808(282K) コミット済み = 16252928(15872K) 最大 = 259522560(253440K)
深度が 1500 の場合
init = 16777216(16384K) used = 288808(282K) commit = 16252928(15872K) max = 259522560(253440K) 15872K) 最大 = 259522560(253440K) 空きメモリ 15873528 初期化 = 16777216(16384K) 使用済み = 379400(370K) コミット済み = 16252928(15872K) 最大 = 259522560(253440K)
depth が 6000 の場合
init = 16777216(16384K) used = 288808(282K) commit = 16252928(15872K) max = 259522560(253440K) 15872K) 最大 = 259522560(253440K) 空きメモリ 15692784 初期化 = 16777216(16384K) 使用済み = 560144(547K) コミット済み = 16252928(15872K) 最大 = 259522560(253440K)
depth が 6500 の場合 (スレッド「main」で例外 java.lang.StackOverflowError)
init = 16777216(16384K) used = 288808(282K) commit = 16252928(15872K) max = 259522560(253440K) 15872K) 最大 = 259522560(253440K)
私の質問は次のとおりです。
- finalize() を呼び出していません。メモリリークですか?
- N=1000まで空きメモリに変化はありません。ただし、N=1500 の場合、プログラムの最後に使用されるメモリには 2 つの異なる値、つまり 282K と 370K があります。なぜそうなるのですか?
- N=6500 の場合、JVM はエラーを生成します。では、なぜ try{} の最後の 2 つのステートメントが実行されるのでしょうか。