Item 7. 書き上げたオブジェクトの参照を解除
1807 ワード
Javaでは、メモリを管理するゴミ回収(GC)が存在し、ユーザのメモリ管理の負担が軽減される.
ただしGCはすべてのメモリを管理することはできません.自分が直接メモリを管理しているクラスについてはGCの管理から外れてしまいますが、クラス内部のメモリ漏れを防ぐためには防犯が必要です.
簡単なメモリリークスタッククラスを次に示します.
ちょうどpop()をする時です.上のコードから見るとpop()と簡単にsizeを縮小する操作しかしません.size内部のデータは、使用する領域が「アクティブ領域」であることを示す.アクティブな領域の外にすべてのデータの参照(古い参照)を書き込みます.書き終わった参照はまだ存在するのでnull処理を行う必要があります.
pop()の変更
では、すべてのオブジェクトは書き終わるとnull処理をしますか?そうではありません.このようにnull処理を1つずつ行うと,コードが乱雑になる.
可能であれば、有効範囲(scope)の外に出して、いっそ参考にさせないほうがいいです.
以上のように、メモリを直接管理するクラスはGCの管理から外れますので、常にメモリリークに注意してください.
また、メモリ漏洩の1つの原因はキャッシュです.オブジェクトリファレンスをキャッシュに忘れた場合は、メモリ漏洩のトリガポイントが保持されているのと同じです.
対応策はWeakHashMapを使用してキャッシュを作成することです.
弱参照(Weak Reference)として作成し、GCの領域に配置します.
3つ目はリスナーとコールバックです.クライアントはコールバックを登録していますが、コールバックは明確に解除されないため、コールバックは蓄積されます.この場合、弱い参照としてコールバックに格納されると、GCは直ちに回収される.
ただしGCはすべてのメモリを管理することはできません.自分が直接メモリを管理しているクラスについてはGCの管理から外れてしまいますが、クラス内部のメモリ漏れを防ぐためには防犯が必要です.
簡単なメモリリークスタッククラスを次に示します.
public class Stack{
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack(){
return elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
pulbic void push(Object e){
ensureCapacity();
elemetes[size++] = e;
}
public Obejct pop(){
if( size == 0 )
throw new EmptyStackException();
return elementes[--size];
}
private void ensureCapacity(){
// 공간을 두 배로 늘린 후, 복붙
if(elements.length == size)
elements = Array.copyOf(elements, 2 * size +1);
}
}
一見問題ない.しかし、よく見るとメモリ漏れの危険性がわかります.では、どこでメモリ漏れが発生しますか?ちょうどpop()をする時です.上のコードから見るとpop()と簡単にsizeを縮小する操作しかしません.size内部のデータは、使用する領域が「アクティブ領域」であることを示す.アクティブな領域の外にすべてのデータの参照(古い参照)を書き込みます.書き終わった参照はまだ存在するのでnull処理を行う必要があります.
pop()の変更
public Object pop(){
if(size==0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // 다 쓴 참조 객체
return result;
}
書き終わったオブジェクトを残してうっかりアクセスすると、NullPointerExceptionを投げ出してすぐにプログラムを終了します.では、すべてのオブジェクトは書き終わるとnull処理をしますか?そうではありません.このようにnull処理を1つずつ行うと,コードが乱雑になる.
可能であれば、有効範囲(scope)の外に出して、いっそ参考にさせないほうがいいです.
以上のように、メモリを直接管理するクラスはGCの管理から外れますので、常にメモリリークに注意してください.
また、メモリ漏洩の1つの原因はキャッシュです.オブジェクトリファレンスをキャッシュに忘れた場合は、メモリ漏洩のトリガポイントが保持されているのと同じです.
対応策はWeakHashMapを使用してキャッシュを作成することです.
弱参照(Weak Reference)として作成し、GCの領域に配置します.
3つ目はリスナーとコールバックです.クライアントはコールバックを登録していますが、コールバックは明確に解除されないため、コールバックは蓄積されます.この場合、弱い参照としてコールバックに格納されると、GCは直ちに回収される.
Reference
この問題について(Item 7. 書き上げたオブジェクトの参照を解除), 我々は、より多くの情報をここで見つけました https://velog.io/@simgyuhwan/Item-7.-다-쓴-객체-참조를-해제하라テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol