您的位置:首页 > 其它

ThreadLocal是否会引起内存溢出?

2013-02-11 19:50 295 查看
最近碰到一个使用ThreadLocal时因为未调用remove()而险些引起内存溢出的问题,所以看了下ThreadLocal的源码,结合线程池原理做一个简单的分析,确认是否最终会导致内存溢出。

既然是因为没调用remove()方法而险些导致内存溢出,那首先看下remove()方法中做了什么。

Java代码







public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}

public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}


从remove()的实现来看就是一个map.remove()的调用。既然不调用map.remove()可能会引起内存溢出的话,就需要看看ThreadLocalMap的实现了。

Java代码







/**
* ThreadLocalMap is a customized hash map suitable only for

* maintaining thread local values. No operations are exported

* outside of the ThreadLocal class. The class is package private to

* allow declaration of fields in class Thread. To help deal with

* very large and long-lived usages, the hash table entries use

* WeakReferences for keys. However, since reference queues are not

* used, stale entries are guaranteed to be removed only when

* the table starts running out of space.

*/
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> {
/** The value associated with this ThreadLocal. */
Object value;

Entry(ThreadLocal k, Object v) {
super(k);
value = v;
}
}

/**
* The initial capacity -- MUST be a power of two.

*/
private static final int INITIAL_CAPACITY = 16;

/**
* The table, resized as necessary.
* table.length MUST always be a power of two.

*/
private Entry[] table;

/**
* The number of entries in the table.

*/
private int size = 0;

/**
* The next size value at which to resize.

*/
private int threshold; // Default to 0

/**
* Set the resize threshold to maintain at worst a 2/3 load factor.

*/
private void setThreshold(int len) {
threshold = len * 2 / 3;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: