JVMメモリ漏洩の簡単な例


記事JVMがオブジェクトの「死」と「生」をどのように判断するかでは,オブジェクトの生存の有無をどのように判断するかを紹介し,ルート探索アルゴリズムについて述べ,GC Rootsとオブジェクトの生死属性を判断する通路があるかどうかについて述べた.では、java仮想マシンの送信メモリの漏洩の原因は何なのか、主に以下の2つの特徴があります.
(1)割り当てられたオブジェクトは可,すなわち有向図においてGC Rootsと経路がある.
(2)ただし,このオブジェクトは以降のプログラムでは使用されなくなり,すなわちオブジェクトは不要となる.
上記の2つの特徴を満たすと,メモリリークと判定され,これらのオブジェクトはGCで回収されないが,メモリを占有している.
簡単な例を挙げてみましょう.
package cn.com.yy;

import java.util.Vector;

/**
 *          
 * @author yy
 * @time 2014-10-3   10:41:42
 */
public class MemoryLeakTest {

	public static void main(String[] args) {
		Vector v = new Vector(100000000);
		for(int i=0;i<v.size();i++){
			Object o = new Object();
			v.add(o);
			o = null;
		}
	}
}
はこのプログラムを実行し、結果は以下の通りである.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Vector.<init>(Vector.java:131)
	at java.util.Vector.<init>(Vector.java:144)
	at cn.com.yy.MemoryLeakTest.main(MemoryLeakTest.java:13)
解析:
forループでは、申請Objectオブジェクトをループし、申請ごとにVectorに入れ、Objectオブジェクトを空にします.このとき、ObjectオブジェクトについてはGC Rootsとパスがあり、Vectorオブジェクトによって参照されているが、Objectオブジェクトが空になった後、Objectオブジェクトはまた用途がないため、すべてのObjectオブジェクトについてはGC Rootsとパスがあるが、役に立たないため、スタックメモリリークとなる.