4

次のようなコードがある場合:

public class MyActivity extends Activity 
{

private SingletonClass singletonInstance;

...

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    singletonInstance = SingletonClass.getInstance();
}

...
}

私の理解では、アクティビティは静的インスタンスへの参照を持っているため、GC に失敗するため、存続するということです。ただし、アプリケーションで問題が発生することはないようです。私は GC を理解していないのでしょうか、それともこれは本当にメモリ リークを起こしているのでしょうか?

4

2 に答える 2

1

あなたの疑問について調査し、私の答えを確認します:

singletonInstance を static として宣言した場合に発生します。アクティビティの場合、singletonInstance は SingletonClass の単なるインスタンスです。「静的インスタンス」のようなものは存在しないことを思い出してください。インスタンスは特定のクラスの単なるオブジェクトであり、静的にするのはスコープ内で宣言する方法です。MyActivity の場合、SingletonClass 内で同じオブジェクト/インスタンスを参照していて、そこで static として宣言されていても、singletonInstance は static ではありません。

このようにして、Activity を問題なく GC でクリーンアップできます。私はAndroidで同様の実装を行っており、それにはサービスが含まれており、メモリやパフォーマンスの問題なしで何百時間も実行されています...

よろしく

于 2013-05-24T13:55:40.930 に答える
1

Square の LeakCanary を使用して Android アプリのメモリ リークを検出しましたが、静的なシングルトン obj が保持する参照が原因で、Activity の 1 つでリークが検出されました。

My Activity は Q と同じ構造で、Activity にはシングルトン Presenter クラスへの参照がありますが、参照は静的ではありません。

public MyActivity extends Activity {
  private MyPresenter mPresenter;
  ...
  onCreate() {
     mPresenter = MyPresenter.getInstance()
     ...
  }
}
..
public class MyPresenter { // Different class
 private static MyPresenter mInstance;
... singleton code ...
}

このリンクを読んで、それは理にかなっていると思います。http://www.javaworld.com/article/2071737/core-java/plug-memory-leaks-in-enterprise-java-applications.html

Singleton クラスがインスタンス化されると、アプリケーションの存続期間中、メモリ内に残ります。他のオブジェクトもそれへのライブ参照を持ち、その結果、ガベージ コレクトされることはありません。

推奨事項:- 永続的なオブジェクトからオブジェクトを参照することは避けてください。このような使用を避けることができない場合は、弱い参照を使用します。これは、オブジェクトがガベージ コレクションされるのを妨げないタイプのオブジェクト参照です。

于 2015-12-21T19:25:05.673 に答える