Java では、静的変数はヒープ上に存在し、クラスのロード時に割り当てられます。インスタンス変数のガベージ コレクションの適格性は、そのインスタンスに関連付けられています。
値型 (int、bool、double など) の静的変数を使用しても、クラスのインスタンスはリークしません。非値型の静的変数を許可すると、これらの静的変数によって参照されるものはすべてリークする可能性があります。
簡単なクラスを考える
public class Activity extends Context {
static int willNotLeakActivity = 0;
static Context mayLeakActivity = new Context();
//if you call activityA.leakyMethod(activityA); you will leak activityA
public void leakyMethod(Context context){
mayLeakActivity = context;
}
//this method won't leak the instance
public void safeMethod(int arg){
willNotLeakActivity = arg;
}
}
Activity オブジェクトへの参照を (参照型が Context であっても) 静的変数に保持すると、Activity オブジェクトがリークします。
Android は実際の JVM ではなく、Dalvik VM で実行されることに注意してください。そのため、理論上は結果が異なる場合がありますが、GC の適格性に関する限り、Dalvik が異なることに非常に驚いています (私は自分で問題に遭遇することはありません)。
編集 - 質問をもう一度見てみると、これで理解が深まるかもしれないと思います。オブジェクトは、GC ルートから参照チェーンをたどって到達できる限り、ガベージ コレクションの対象にはなりません。アクティビティ オブジェクトは、Android プロセスによってインスタンス化され、正常に維持されます (これは、少なくともstatic void main(string[] args)
.
システムが yourActivityInstance.onDestroy() を呼び出して参照を解放すると、別の参照を介して GC ルートからアクティビティのインスタンスに到達できない限り、そのオブジェクト (およびその後、それが参照するすべてのオブジェクト) を GC する資格があります。この参照が保持されるべきよりも長く保持されている場合 (読み取り: 無期限)、GC はリークされたオブジェクトのリソースを安全に解放できるかどうかを確認できないため、このオブジェクトをリークしています。
この参照がどのように保持されるか (静的または非静的、最終的または非最終的) は問題ではありません。オブジェクトが GC ルート (少なくとも静的メソッドのローカル変数とスコープ内変数、ロードされたクラスの静的フィールド) から到達できる限り、リークが発生します。