【Android FAQ】メモリリークについて(2)


Androidでよく見られる問題の1つは、メモリが漏洩しやすいという問題です.
  • 単一例はメモリ漏洩を引き起こす:単一例の静的特性はそれを非常に特別にし、往々にしてそのライフサイクルはアプリケーションのライフサイクルと同じように長い.使用中に制限や管理を行わないと、大量の単一の例でメモリが大量に消費され、最終的にはメモリが漏洩します.
  • `public class MyClass {
    private static MyClass instance;
    private Context context;
    private MyClass (Context context) {
    this.context = context;
    }
    public static MyClass getInstance(Context context) {
    if (instance != null) {
    instance = new MyClass (context);
    }return instance;
    }
    }`

    以上の例は極めて一般的であり、単一の例を作成する際には、パラメータcontextを導入する必要があります.このcontextのライフサイクルは、単一の例のライフサイクルに影響を与えます.転送されるcontextには、2つの状況があります.
  • アプリケーションのcontext.アプリケーションのライフサイクルはアプリケーション全体のライフサイクルであることがわかりますので、アプリケーションを参照しても問題はありません.
  • Activityのcontext.contextに対応するactivityが終了した場合、contextの参照は単一のオブジェクトによって保持され、ライフサイクルはアプリケーション全体のライフサイクル、すなわちActivityの終了が存在するが、メモリが解放されていない場合、最終的な結果はメモリ漏洩であるに違いない.
  • 非静的内部クラス静的インスタンスの作成:
  • public class MainActivity extends AppCompatActivity {
    private static TestResource mResource = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if(mResource == null){
    mResource = new TestResource();
    }//...}class TestResource {//...}
    }

    このインスタンスのアプローチは、同じデータリソースの重複作成を回避するためです.重複作成は回避されますが、非静的内部クラスは外部クラスの参照をデフォルトで保持し、非静的内部クラスは静的インスタンスを作成し、インスタンスのライフサイクルがアプリケーションと同じ長さであるため、静的インスタンスはActivityの参照を常に保持しているため、Activityのメモリリソースは正常に回収されません.
  • HandlerによるメモリリークHandlerの使用は非常に一般的であり、主スレッドでの時間のかかる操作を回避するために、時間のかかる操作の問題を解決する必要がある場合にHandlerを利用することが多い.しかしHandlerは万能ではなく、使用が規範化されていないとメモリが漏れてしまいます.HandlerはTLS(Thread Local Storage)変数に属するため、ライフサイクルとActivityは一致しません.そのため、このような実装方式は、一般に、ViewまたはActivityのライフサイクルと一致することを保証することが困難であるため、正しく解放されない可能性が高い.