ThreadLocal是否会引起内存溢出?

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

既然是因为没调用remove()方法而险些导致内存溢出,那首先看下remove()方法中做了什么。
Java代码 复制代码 收藏代码
  1. public void remove() {   
  2.         ThreadLocalMap m = getMap(Thread.currentThread());   
  3.         if (m != null)   
  4.             m.remove(this);   
  5.     }  

从remove()的实现来看就是一个map.remove()的调用。既然不调用map.remove()可能会引起内存溢出的话,就需要看看ThreadLocalMap的实现了。
Java代码 复制代码 收藏代码
  1.  /**  
  2.   * ThreadLocalMap is a customized hash map suitable only for  
  3.   * maintaining thread local values. No operations are exported  
  4.   * outside of the ThreadLocal class. The class is package private to  
  5.   * allow declaration of fields in class Thread.  To help deal with  
  6.   * very large and long-lived usages, the hash table entries use  
  7.   * WeakReferences for keys. However, since reference queues are not  
  8.   * used, stale entries are guaranteed to be removed only when  
  9.   * the table starts running out of space.  
  10.   */  
  11.  static class ThreadLocalMap {   
  12.   
  13.      /**  
  14.       * The entries in this hash map extend WeakReference, using  
  15.       * its main ref field as the key (which is always a  
  16.       * ThreadLocal object).  Note that null keys (i.e. entry.get()  
  17.       * == null) mean that the key is no longer referenced, so the  
  18.       * entry can be expunged from table.  Such entries are referred to  
  19.       * as "stale entries" in the code that follows.  
  20.       */  
  21.      static class Entry extends WeakReference<ThreadLocal> {   
  22.          /** The value associated with this ThreadLocal. */  
  23.          Object value;   
  24.   
  25.          Entry(ThreadLocal k, Object v) {   
  26.              super(k);   
  27.              value = v;   
  28.          }   
  29.      }   
  30.   
  31.      /**  
  32.       * The initial capacity -- MUST be a power of two.  
  33.       */  
  34.      private static final int INITIAL_CAPACITY = 16;   
  35.   
  36.      /**  
  37.       * The table, resized as necessary.  
  38.       * table.length MUST always be a power of two.  
  39.       */  
  40.      private Entry[] table;   
  41.   
  42.      /**  
  43.       * The number of entries in the table.  
  44.       */  
  45.      private int size = 0;   
  46.   
  47.      /**  
  48.       * The next size value at which to resize.  
  49.       */  
  50.      private int threshold; // Default to 0   
  51.   
  52.      /**  
  53.       * Set the resize threshold to maintain at worst a 2/3 load factor.  
  54.       */  
  55.      private void setThreshold(int len) {   
  56.          threshold = len * 2 / 3;   
  57.      }   
posted on 2013-02-11 19:50  蜜雪薇琪  阅读(284)  评论(0编辑  收藏  举报