スレッドには、誰もが頻繁に呼び出すメソッドがあります。それが ThreadLocal です。ただし、ThreadLocal はメモリ処理においてより困難な問題にも遭遇し、何らかのメモリ リークが常に発生します。この記事では、漏洩の例を使用して誰でも分析できるようにします。また、漏洩の状況を理解し、ThreadLocal に対応するソリューションを提案するのにも役立ちます。
1. 漏水例
ThreadLocalMap の静的内部クラス エントリ:
static class Entry extends WeakReference<ThreadLocal<?>> { /** この ThreadLocal に関連付けられた値 */ オブジェクトの値。 Entry(ThreadLocal<?> k, Object v) { スーパー(k); 値 = v; } }
ThreadLocalMap は静的内部クラス Entry を使用して <k, v> ストレージを実装し、Entry は WeakReference クラスを継承するため、ThreadLocalMap のキーは実際には ThreadLocal への弱参照になります。
ThreadLocalMap は ThreadLocal の弱参照をキーとして使用しているため、この ThreadLocal に外部強参照がない場合は GC になります。このとき、ThreadLocalMap には null キーを持つ Entry が表示されますが、この Entry の値にはアクセスできません。
この場合、現在の作業スレッドが終了していない場合、null キーを持つ値は Entry によって強く参照され、Entry は現在のスレッドの ThreadLocalMap によって強く参照されるため、この値は GC されず、メモリが使用されなくなります。リーク。
2. 解決策
ThreadLocalMap の cleanSomeSlots() メソッドと expungeStaleEntry() メソッドは、null キーを含む値をクリアできます。 ThreadLocal の set()、get()、remove() メソッドでは、cleanSomeSlots() または expungeStaleEntry() が呼び出され、ThreadLocalMap 内の null キーを持つすべての値がクリアされます。
上記は Java ThreadLocal メモリ リークの解決策です。もちろん、これはメモリ リークに対して一定の役割を果たすだけであり、それが発生しないという保証はありません。