标签:get key set inf warning long weakref zed nbsp
1 ThreadLocal?
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its
get() or set()) has its own, independently initialized copy of the variable instances are typically private
static fields in classes that wish to associate state with a thread . (这个类提供了线程本地变量,这些线程本地变量不同于普通变量,因为每一个线程都独立拥有这些变量的一份copy)
Thread类中(ThreadLocalMap)threadLocals变量 十分重要,ThreadLocalMap类中Entry extends WeakReference<ThreadLocal> key
是threadLocal变量本身,value是存放的对象 ,由于entry的key是弱引用,所以当一次Gc的时候(不管此时内存够不够),弱引用的对象都被回收,而与之关联的value一直存在,entry一直被线程强引用,如果线程是在线程池中,线程不被释放,其强应用的对象也就一直不被释放,不断创建对象,导致thread强引用的entry不断增多,从而导致内存泄露
盗一个图:
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue(); //内存泄露理解关键点1,强引用
}
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value); //内存泄露理解关键点1,强引用
return value;
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
/**
* Create the map associated with a ThreadLocal. Overridden in
* InheritableThreadLocal.
*
* @param t the current thread
* @param firstValue value for the initial entry of the map
*/
void createMap(Thread t, T firstValue) { //内存泄露理解关键点1,强引用
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
static class ThreadLocalMap {
/**
* The entries in this hash map extend WeakReference, using
* its main ref field as the key (which is always a
* ThreadLocal object). Note that null keys (i.e. entry.get()
* == null) mean that the key is no longer referenced, so the
* entry can be expunged from table. Such entries are referred to
* as "stale entries" in the code that follows.
*/
static class Entry extends WeakReference<ThreadLocal<?>> { //内存泄露理解关键点2 即 key是弱引用
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
}
标签:get key set inf warning long weakref zed nbsp
原文地址:https://www.cnblogs.com/xiamingqing/p/13371117.html