簡単な例があります。この例では、10000000のランダムな整数を含むArrayList<Integer>
ファイルからをロードしf
ます。
doLog("Test 2");
{
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
List<Integer> l = (List<Integer>) ois.readObject();
ois.close();
fis.close();
doLog("Test 2.1");
//l = null;
doLog("Test 2.2");
}
doLog("Test 2.3");
System.gc();
doLog("Test 2.4");
私が持っているときl = null
、私はこのログを取得します:
Test 2 Used Mem = 492 KB Total Mem = 123 MB
Test 2.1 Used Mem = 44 MB Total Mem = 123 MB
Test 2.2 Used Mem = 44 MB Total Mem = 123 MB
Test 2.3 Used Mem = 44 MB Total Mem = 123 MB
Test 2.4 Used Mem = 493 KB Total Mem = 123 MB
しかし、それを削除すると、代わりにこのログが表示されます。
Test 2 Used Mem = 492 KB Total Mem = 123 MB
Test 2.1 Used Mem = 44 MB Total Mem = 123 MB
Test 2.2 Used Mem = 44 MB Total Mem = 123 MB
Test 2.3 Used Mem = 44 MB Total Mem = 123 MB
Test 2.4 Used Mem = 44 MB Total Mem = 123 MB
Used Memory
によって計算されます: runTime.totalMemory() - runTime.freeMemory()
質問:ケースでl = null;
存在している、メモリリークがありますか?l
にアクセスできないのに、なぜそれを解放できないのですか?
上記のコードにはメモリリークはありません。
コードブロックをで囲んだままにする{}
と、変数l
はスコープ外になり、最初にList
設定したかどうかに関係なく、はガベージコレクションの候補になりますnull
。
ただし、コードブロックの後、メソッドが戻るまで、List
はinvisibleと呼ばれる状態にあります。これは事実ですが、JVMが参照を自動的にnullにしてList
のメモリを収集することはほとんどありません。したがって、明示的に設定l = null
すると、JVMがメモリ計算を行う前にメモリを収集するのに役立ちます。それ以外の場合は、メソッドが戻るときに自動的に発生します。
ガベージコレクターがいつ実行されるか正確にはわからないため、コードの実行ごとに異なる結果が得られる可能性があります。あなたはそれを使って実行すべきだと思うことを提案できますSystem.gc()
(そしてそれはList
設定なしでも見えないものを収集するかもしれませんl = null
)が、約束はありません。これはSystem.gc()のjavadocに記載されています。
gcメソッドを呼び出すと、Java Virtual Machineが未使用のオブジェクトをリサイクルして、現在それらが使用しているメモリをすばやく再利用できるようにするための労力が費やされることを示唆しています。メソッド呼び出しから制御が戻ったとき、Java仮想マシンは、破棄されたすべてのオブジェクトからスペースを回収するために最善の努力をしました。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加