Hay un método en los hilos que todos llaman con frecuencia, y ese es ThreadLocal. Sin embargo, ThreadLocal también encontrará problemas más difíciles en el procesamiento de la memoria y siempre se producirán algunas pérdidas de memoria. Este artículo utilizará un ejemplo de fuga para analizarlo para todos y también lo ayudará a comprender algunas situaciones de fuga y propondrá las soluciones correspondientes a ThreadLocal.
1. Ejemplos de fugas
Entrada de clase interna estática de ThreadLocalMap:
La entrada de clase estática extiende WeakReference<ThreadLocal<?>> { /** El valor asociado con este ThreadLocal */ Valor del objeto; Entrada(ThreadLocal<?> k, Objeto v) { super(k); valor = v; } }
ThreadLocalMap usa la clase interna estática Entry para implementar el almacenamiento <k, v>, y Entry hereda la clase WeakReference, por lo que la clave en ThreadLocalMap es en realidad una referencia débil a ThreadLocal.
Precisamente porque ThreadLocalMap utiliza la referencia débil de ThreadLocal como clave, cuando este ThreadLocal no tiene una referencia fuerte externa, será GC. En este momento, aparecerá una entrada con una clave nula en ThreadLocalMap. Por supuesto, nunca se accederá al valor de esta entrada.
En este caso, si el subproceso de trabajo actual no ha finalizado, Entry hace referencia fuerte al valor con una clave nula, y ThreadLocalMap del subproceso actual hace referencia fuerte a Entry, lo que hace que este valor nunca se GCed, lo que provoca una pérdida de memoria. filtración.
2. Solución
Los métodos cleanSomeSlots() y expungeStaleEntry() de ThreadLocalMap pueden borrar valores con claves nulas. En los métodos set(), get() y remove() de ThreadLocal, se llamará a cleanSomeSlots() o expungeStaleEntry() para borrar todos los valores con claves nulas en ThreadLocalMap.
Lo anterior es la solución a la pérdida de memoria de Java ThreadLocal. Por supuesto, esto solo puede desempeñar un cierto papel en la pérdida de memoria. Después de todo, es solo una especie de claridad y no hay garantía de que no ocurra .