欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

分析ThreadLocal内存泄漏问题,

来源: javaer 分享于  点击 49484 次 点评:40

分析ThreadLocal内存泄漏问题,


目录
  • ThreadLocal的实现原理
  • ThreadLocal为什么会内存泄漏
    • 为什么使用弱引用
  • ThreadLocal最佳实践

    ThreadLocal的实现原理

    ThreadLocal的实现:

    每一个Thread内部维护一个ThreadLocalMap映射表,这个映射表的keyThreadLocal实例本身,value是真正需要存储的Object

    也就是说ThreadLocal本身不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value的。但是ThreadLocalMap是使用ThreadLocal的弱引用作为key的,弱引用的对象在GC时会被回收。

    ThreadLocal为什么会内存泄漏

    ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统GC的时候,这个ThreadLocal会被回收,这样一来,ThreadLocalMap中会出现keynullEntry,这样就没有办法访问keynullEntryvalue,如果当前线程迟迟不结束,这些keynullEntryvalue就会存在一条强引用链,永远无法回收,造成内存泄漏。

    其实ThreadLocal的设计中已经考虑到了这种情况,也加上了一些预防措施,在调用getsetremove方法的时候,会清楚线程ThreadLocalMap里所有keynullvalue

    但是这些被动的预防措施并不能保证不会内存泄漏:

    • 使用staticThreadLocal,延长了ThreadLocal的生命周期,可能导致的内存泄漏。
    • 分配使用了ThreadLocal又不再调用get() ,set() ,remove() 方法,那么就会导致内存泄漏。

    为什么使用弱引用

    从表面上看内存泄漏的根本原因是使用了弱引用,那么为什么使用弱引用而不使用强引用呢?下面看看官方文档的说法:

    To help deal with very large and long-lived usages, the hash table entries use WeakReferences for keys.

    翻译过来就是:为了应对非常大和长时间的用途,哈希表使用弱引用。

    下面我们分两种情况讨论:

    • key 使用强引用:引用的ThreadLocal的对象被回收了,但是ThreadLocalMap还持有ThreadLocal的强引用,如果没有手动删除,ThreadLocal不会被回收,导致Entry内存泄漏。
    • key 使用弱引用:引用的ThreadLocal的对象被回收了,由于ThreadLocalMap持有ThreadLocal的弱引用,即使没有手动删除,ThreadLocal也会被回收。value在下一次ThreadLocalMap调用set,getremove的时候会被清除。

    比较两种情况,我们可以发现:由于ThreadLocalMap的生命周期跟Thread一样长,如果都没有手动删除对应key,都会导致内存泄漏,但是使用弱引用可以多一层保障:弱引用 ThreadLocal 不会内存泄漏,对应的 value 在下一次 ThreadLocalMap 调用 set , get , remove 的时候会被清除

    因此,ThreadLocal内存泄漏的根源是:由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏,而不是因为弱引用。

    ThreadLocal最佳实践

    综合上面的分析,我们可以理解ThreadLocal内存泄漏的前因后果,那么怎么避免内存泄漏呢?

    • 每次使用完ThreadLocal,都调用它的remove() 方法,清除数据。

    在使用线程池的情况下,没有及时清理ThreadLocal,不仅是内存泄漏的问题,更严重的是可能导致业务逻辑出现问题。所以,使用ThreadLocal就跟加锁完要解锁一样,用完就清理。

    到此这篇关于分析ThreadLocal内存泄漏问题的文章就介绍到这了,更多相关ThreadLocal内存泄漏内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

    您可能感兴趣的文章:
    • Java中ThreadLocal避免内存泄漏的方法详解
    • ThreadLocal导致JVM内存泄漏原因探究
    • 对ThreadLocal内存泄漏及弱引用的理解
    • ThreadLocal内存泄漏常见要点解析
    • ThreadLocal内存泄漏问题解决方案
    • ThreadLocal原理及内存泄漏原因
    相关栏目:

    用户点评