質問: Android の `Context` について教えて下さい。 引数などとして渡す `Context` ですが `this` を使うのではなく`getApplicationContext()` を推奨されているブログを以前見ました。 `this` を使うとメモリを解放しても参照先が残るので、蓄積するとメモリリークになる可能性があるので `getApplicationContext()` を使うべきだとのこと。 そこで質問ですが参照先が残るという挙動を確認する方法ってあるのでしょうか?
回答: @zaki50 さんのと考え方は同じですが、別解です。 @zaki50 さんのやりかただと、`ref.get()`がリファレントの実体(i.e. `Context`インスタンス)を返すため、コードの書き方によってはGCを邪魔してしまいます。また、GCを待つために何度も`ref.get()`を実行する必要が出てくるかもしれません。 これらをさけるために`ReferenceQueue`が使えます。これに`WeakReference`を登録しておくと、そのリファレントへの参照がなくなったときに`ReferenceQueue`を通して通知を受け取ることができます。 まず、`Context`インスタンスを使う辺りで、それを以下の様に`ReferenceQueue`に登録します。 ``` ReferenceQueue queue = new ReferenceQueue<>(); WeakReference ref = new WeakReference<>(this, queue); ``` これらの`queue`と`ref`は、後で参照できてGCされないどこかに保持しておきます。 次に、登録したインスタンスへの参照がなくなったと思うところで、以下を実行し、本当になくなったことを確認できます。 ``` System.gc(); queue.remove(); System.out.println("参照なくなった"); ``` 登録したインスタンスへの参照がなくなったことにガーベジコレクタが気付くと、ガーベジコレクタはそのインスタンスの`WeakReference`を`queue`に突っ込みます。 `queue.remove()`は`queue`に`WeakReference`が突っ込まれるまでブロックするので、ループ等しなくてもGCを待てます。 `queue.remove()`が返すのは登録したインスタンスそのものではなく、その`WeakReference`なので、GCのじゃまも一切しません。