美文网首页
ThreadLocal原理及内存泄露以及最佳实践

ThreadLocal原理及内存泄露以及最佳实践

作者: chozee | 来源:发表于2021-01-19 15:49 被阅读0次

    Thread.currentThread.map当前线程的map
    map的key是ThreadLocal的实例
    当ThreadLocal被回收时,其key为null,但value可能泄露与内存所以采用弱引用

    ThreadLocal的map的Entry为什么采用弱引用

    防止内存泄漏,tl本身为null时,无法及时回收key为null的value
    key 使用弱引用:引用的ThreadLocal的对象被回收了,由于ThreadLocalMap持有ThreadLocal的弱引用,即使没有手动删除,ThreadLocal也会被回收。value在下一次ThreadLocalMap调用set,get,remove的时候会被清除
    

    ThreadLocal用途
    声明式识事务

    ThreadLocal原理
    每个Thread 维护一个 ThreadLocalMap 映射表,这个映射表的 key 是 ThreadLocal实例本身,value 是真正需要存储的 Object
    ThreadLocal 本身并不存储值,它只是作为一个 key 来让线程从 ThreadLocalMap 获取 value
    ThreadLocalMap 是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收

    ThreadLocal导致内存泄露

    ThreadLocalMap的生命周期跟Thread一样长
    
    ThreadLocalMap使用ThreadLocal的弱引用作为key,
    如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,
    这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的
    Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话(线程池重用线程),
    这些key为null的Entry的value就会一直存在一条强引用链:
    Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,
    造成内存泄漏。
    
    ThreadLocal的措施
        get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value
        但无法保证 
        
            static的ThreadLocal,延长了ThreadLocal的生命周期,可能导致的内存泄漏
            分配使用了ThreadLocal又不再调用get(),set(),remove()方法,那么就会导致内存泄漏
    

    ThreadLocal最佳实践
    每次使用完ThreadLocal,都调用它的remove()方法,清除数据
    在使用线程池的情况下,没有及时清理ThreadLocal,不仅是内存泄漏的问题,更严重的是可能导致业务逻辑出现问题。所以,使用ThreadLocal就跟加锁完要解锁一样,用完就清理

    相关文章

      网友评论

          本文标题:ThreadLocal原理及内存泄露以及最佳实践

          本文链接:https://www.haomeiwen.com/subject/lutczktx.html