这篇文章,主要解决一下疑惑:
1. ThreadLocal.ThreadLocalMap中提到的弱引用,弱引用究竟会不会被回收?
2. 弱引用什么情况下回收?
3. JAVA的ThreadLocal和在什么情况下会内存泄露?
 
带着这些疑问,自己模拟了一下ThreadLocal.ThreadLocalMap的结构,先展示下自己涉及的结构:
自己实现一个simple的ThreadLocalMap,里面用一个entry用来存放由自己模拟的ThreadLocal调用set方法set进去的值。
并且和JDK的ThreadLocalMap一样里面Entry对象的key用weakReference封装。
 
Main方法如下:

  
 
设置运行参数:
-verbose:gc  
 
看输出结果:
 这里我已经模拟出了内存泄露的问题,可以看到FULL
GC以后,内存还是被占用,且仔细观察可以看到,这个map中的Key已经有为null了。换句话说你通过Key已经不能获取到value了,当然map.get(null)也是可以的,不过
JAVA里的ThreadLocal不会这么去做,因为Map中key==null的元素可能不唯一。
从我的Main方法中可以看到,我有th=null的操作,但是还是有内存泄露,原因稍后分析。但有一点可以确定:th=null在这里不能如我们想象的将ThreadLocal th
的引用释放掉后,里面的key,value对象也释放,可能会有疑问我这里持有了ThreadLocalMap的引用tm所以不会回收,但实际上,手动设置JAVA的ThreadLocal为null时,当前线程任然持有ThreadLocalMap的引用,所以不会回收我这里和JAVA是类似的。
 
回到刚开始提出的3个问题,一一解答:
1. ThreadLocal.ThreadLocalMap中提到的弱引用,弱引用究竟会不会被回收?
     会被回收,如上图所示。key
已经有null的情况了。第一个Key不为null,原因在第二点。在经历过FULL GC后 所有的key都被回收了。
2. 弱引用什么情况下回收?
     弱引用在GC(包括MinitorGC和Full
GC)时,被扫描到就会被回收,但是有一个前提,该弱引用在外部没有被引用到(这个时候外部的引用等于强引用)。
   
 换句话说,如果我main方法中持有一个key的引用,哪怕他put进Map后被设置为弱引用的,也不会被回收。见下图:

GC 日志:

 
     
3.
JAVA的ThreadLocal和在什么情况下会内存泄露?
   答案是不会,原因如下图,在我们调用ThreadLocal.set()的时候,会做一个将Key==
null 的元素清理掉的工作,具体做法是:
     第一步:ThreadLocalMap 拿threadLocalHashCode与长度减一相与,求出哈希表的位置下图中的 i
   
 第二步:编列Entry,如果找到key相等的,覆盖原值! 或者找到key==null的,将值set进去,并且将遍历时路过的key==null的元素和他的value都置为null,,释放内存。
   
 第三步:最后一个if条件时,做rehash的动作,即:将Entry里的元素重新计算一下Hash值,放到合适的位置去,猜想是为了加快下次访问的速度。

 
总结:
   
 从这里看出,JAVA的ThreadLocal对Key使用到了弱引用,但是为了保证不再内存泄露,在每次set.get的时候主动对key==null的entry做遍历回收。
   
 虽然不会造成内存泄露,但是因为只有在每次set,get的时候才会对entry做key==null的判断,从而释放内存,所以可能使大对象在内存中存活很长一段时间,从而占用内存。
   
 所以,我们在使用完ThreadLocal里的对象后最好能手动remove一下,或者至少调用下ThreadLocal.set(null)。
   
 值得注意的是ThreadLocal中的key是当前当前ThreadLocal自己,就像上面模拟的外部持有强引用的情况,ThreadLocal.ThreadLocalMap中的key==null情况很少出现,因为,大部分情况ThreadLocal是以单例模式一直存在的。
  • 大小: 18.7 KB
  • 大小: 15.9 KB
  • 大小: 26.8 KB
  • 大小: 26.4 KB
  • 大小: 39.3 KB
  • 大小: 26.2 KB
 
http://liuinsect.iteye.com/blog/1827012

ThreadLocal是否会引发内存泄露的分析(转)的更多相关文章

  1. ThreadLocal是否会引发内存泄露的分析 good

    这篇文章,主要解决一下疑惑: 1. ThreadLocal.ThreadLocalMap中提到的弱引用,弱引用究竟会不会被回收? 2. 弱引用什么情况下回收? 3. JAVA的ThreadLocal和 ...

  2. 五、jdk工具之jmap(java memory map)、 mat之四--结合mat对内存泄露的分析、jhat之二--结合jmap生成的dump结果在浏览器上展示

    目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...

  3. (转)专项:Android 内存泄露实践分析

    今天看到一篇关于Android 内存泄露实践分析的文章,感觉不错,讲的还算详细,mark到这里. 原文发表于:Testerhome: 作者:ycwdaaaa ;  原文链接:https://teste ...

  4. ThreadLocal是否会导致内存泄露

    什么是内存泄露? 维基百科的定义:[内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存],我的理解就是程序失去了对某段内存的控制,那么这段内存就算是泄露了. ThreadLocal为什么会导致 ...

  5. ThreadLocal深入理解与内存泄露分析

    ThreadLocal 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本.所以每个线程都能够独立地改变自己的副本.而不会影响其他线程所相应的副本. ...

  6. 深入ThreadLocal之三(ThreadLocal可能引起的内存泄露)

    threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好 ...

  7. 小题大做 | Handler内存泄露全面分析

    前言 嗨,大家好,问大家一个"简单"的问题: Handler内存泄露的原因是什么? 你会怎么答呢? 这是错误的回答 有的朋友看到这个题表示,就这?太简单了吧. "内部类持 ...

  8. 查看w3wp进程占用的内存及.NET内存泄露,死锁分析

    一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...

  9. Java 程序的内存泄露问题分析

    什么是内存泄露? 广义的Memory Leak:应用占用了内存,但是不再使用(包括不能使用)该部分内存 狭义的Memory Leak:应用分配了内存,但是不能再获取该部分内存的引用(对于Java,也不 ...

随机推荐

  1. Uva562(dp)

    给我们n个硬币 每个硬币都有它的面值,要我我们分为两堆硬币,使得硬币的差值最小 我们可以dp计算出所有的差值,然后从小到大枚举差值,如果差值存在,就输出 dp[i][j] 表示对于前i件物品能达到差值 ...

  2. hdu2242(树形dp+tarjan+缩点)

    hdu2242 http://acm.hdu.edu.cn/showproblem.php?pid=2242 给定n,m表示n个点,m条边 每个点有个权值 问我们删除两某条边(割边)后将图分为两个部分 ...

  3. HDU 3036 Escape 网格图多人逃生 网络流||二分匹配 建图技巧

    题意: 每一个' . '有一个姑娘, E是出口,'.'是空地 , 'X' 是墙. 每秒钟每一个姑娘能够走一步(上下左右) 每秒钟每一个出口仅仅能出去一个人 给定n*m的地图, 时限T 问全部姑娘是否能 ...

  4. Windows Phone 如果你把Pivot控件当成主页面,那么这篇文章你值得看。

    原文:Windows Phone 如果你把Pivot控件当成主页面,那么这篇文章你值得看. 现在很多App都用到了Pivot视图 来当作 整个App主页面.如果你的Pivot视图主页面承载了大量数据的 ...

  5. 如何使用 yum 安装/更新/移除 软件

    如何使用 yum 安装/更新/移除 软件 一. 建立仓库(repository)和源 a) 拷贝所以相关rpm包到某个目录 b) 执行createrepo  /目录/目录/目录/目录   注意:b)中 ...

  6. Linux System Programming note 8 ——File and Directory Management

    1. The Stat Family #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> ...

  7. Android应用性能測试

    Android内存限制 java虚拟机有内存使用上限的限制 adb shell进入手机,这此參数被纪录在/system/build.prop中,假设想直接查看能够使用adb shell getprop ...

  8. mysql 插入Emoji表情报错

    今天做的了个获取微信粉丝的功能,发现将昵称插入数据库报错.长度肯定是够的 Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F 找了点资料发现UTF-8编 ...

  9. 深入解析_Android的自定义布局

    前言: 这篇文章是前Firefox Android工程师(现在跳槽去Facebook了) Lucas Rocha所写,文中对Android中常用的四种自定义布局方案进行了很好地分析,并结合这四种And ...

  10. 【android】优秀的UI资源站点集合

    1.http://ionicons.com/ 这个站点的图标能满足大部分人的需求.里面包括了经常使用的android风格的图标 ios7风格的图标 以及一些社会化分享图标,总共500个左右.githu ...