内存泄漏
/**
* 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<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
Entry继承自WeakReference, Entry在构造函数使用super(k) 等同于 new WeakReference(key);
也就是将key设置成弱引用, 当key的强引用都断开后,下次gc,key就会被清理掉。
此时Entry的key 就为null了
如果不在key没被gc前,进行remove, 就没办法再通过key找到对应的value, value就会一直存在。
threadlocal有对内存泄漏处理做处理
/**
* Re-pack and/or re-size the table. First scan the entire
* table removing stale entries. If this doesn't sufficiently
* shrink the size of the table, double the table size.
*/
private void rehash() {
expungeStaleEntries();
// Use lower threshold for doubling to avoid hysteresis
if (size >= threshold - threshold / 4)
resize();
}
在扩容时, 会遍历Entry数组,清理掉key为null的数据
但如果一直不扩容, 则内存一直在占用, 所以需要手动清除下