Existe um método em threads que é frequentemente chamado por todos: ThreadLocal. No entanto, ThreadLocal também encontrará problemas mais difíceis no processamento de memória e sempre ocorrerão alguns vazamentos de memória. Este artigo usará um exemplo de vazamento para analisar para todos, e também ajudará você a entender algumas situações de vazamento e propor soluções correspondentes ao ThreadLocal.
1. Exemplos de vazamentos
Entrada de classe interna estática de ThreadLocalMap:
Classe estática Entrada estende WeakReference<ThreadLocal<?>> { /** O valor associado a este ThreadLocal */. Valor do objeto; Entrada(ThreadLocal<?> k, Objeto v) { super(k); valor=v; } }
ThreadLocalMap usa a classe interna estática Entry para implementar o armazenamento <k, v> e Entry herda a classe WeakReference, portanto, a chave em ThreadLocalMap é na verdade uma referência fraca a ThreadLocal.
Precisamente porque ThreadLocalMap usa a referência fraca de ThreadLocal como chave, quando este ThreadLocal não tiver referência externa forte, será GC. Neste momento, uma entrada com chave nula aparecerá em ThreadLocalMap. Obviamente, o valor desta entrada nunca será acessado.
Neste caso, se o thread de trabalho atual não tiver terminado, então o valor com uma chave nula é fortemente referenciado por Entry, e Entry é fortemente referenciado pelo ThreadLocalMap do thread atual, fazendo com que esse valor nunca seja GCed, causando uma memória vazar.
2. Solução
Os métodos cleanSomeSlots() e expungeStaleEntry() do ThreadLocalMap podem limpar valores com chaves nulas. Nos métodos set(), get() e remove() de ThreadLocal, cleanSomeSlots() ou expungeStaleEntry() serão chamados para limpar todos os valores com chaves nulas no ThreadLocalMap.
A descrição acima é a solução para o vazamento de memória Java ThreadLocal. Claro, isso só pode desempenhar um certo papel no vazamento de memória. Afinal, é apenas uma espécie de clareza e não há garantia de que isso não ocorrerá .