Недавно я наблюдал утечку памяти ThreadLocal, и мнений в Интернете много. Самой популярной является утечка памяти, вызванная слабыми ссылками.
почему утечка памяти
1. При каких обстоятельствах ThreadLocal перерабатывается
ThreadLocal
существуетThreadLocalMap
на него ссылается ключ в записи как на слабую ссылку.ThreadLocal
Будет ли он переработан?
Здесь используются упомянутые точки знаний. существуетЧетыре ссылки на javaсказал. Когда на объект указывает сильная ссылка (в данном случае достижимая). Сборщик мусора не будет его перерабатывать.
Например
ThreadLocal threadlocal1 = new ThreadLocal();
threadlocal1.set("测试");
ThreadLocal
Теперь объект имеет два индекса, на которые он указывает.
- Сильная цитата:
threadlocal1
В соответствии с рисунком [1] - Слабая ссылка:
Key(WeakReference(threadlocal1))
Соответствует [2] на рисунке
Поэтому, когда происходит GC, объект ThreadLocal в куче не будет переработан.
Но когда мы ставимthreadlocal1 =null;
При нарушении сильной ссылки, в это времяThreadLoca
Объект l имеет только одну слабую ссылку, поэтому при сборке мусораThreadLocal
объект перерабатывается,Entry
становится ключом с нулемEntry
. Также называется грязным входом
особенность:
- Ключ нулевой, и приложение не может получить доступ к значению, потому что у нас нет на него ссылки.
-
Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value
Цепочка существует, а текущий поток задерживается (например пул потоков), но их нельзя использовать, они становятся грязными данными, что приводит к утечке памяти.
Похоже на утечку памяти, вызванную мягкой ссылкой.
2. Зачем использовать слабые ссылки
Затем проведите сильный эталонный анализ:ThreadLocal
на объект указывают две сильные ссылки
- Сильная ссылка: threadlocal1
- Сильная ссылка: Entry.key
Когда мы ломаем сильную ссылку в программеthreadlocal1
Время.ThreadLocal
Объект по-прежнему имеет сильную ссылкуEntry.key
указывают на, не будут переработаны, в результате чего,ThreadLocal
объект сvalue
становятся грязными данными.
Сравните эти два случая:Независимо от мягких ссылок или сильных ссылок могут возникать утечки памяти, но слабые ссылки уменьшают степень утечек памяти.
использование слабых ссылокЗапись будет иметь особенность, что ключ является нулевым, вы можете определить, какие данные не используются, выполнить операции очистки, слабые ссылки Вместо этого он повышает безопасность ThreadLocal.
На самом деле при вызовеThreadLocal
изget(),set(),reomve()
метод, очистит потокThreadLocalMap
Во всех записях значение ключа равно null, и вся запись имеет значение null, что полезно для следующего восстановления памяти.
3. Истинная причина утечки
Итак: настоящая причина утечки памяти ThreadLocal:
-
ThreadLocalMap
Жизненный цикл Thread такой же длинный, как и у Thread.Если пул потоков не удаляется, например, пул потоков, это может привести к утечке памяти. - Если его вовремя не очистить после использования, он больше не будет вызываться
get()、set()、remove()
Очистите грязные записи
Это настоящая причина утечки памяти.
Суммировать:
Удалить вовремя после использования - самый аутентичный способ использования.
Если есть какие-либо ошибки, сообщите нам об этом и учитесь вместе.
Ссылаться на: