zoukankan      html  css  js  c++  java
  • ThreadLocal内存泄露原因,如何避免

    内存泄漏为程序在申请内存后,无法释放已申请的内存空间,一次泄露危害可以忽略,但内存泄漏堆积后果很严重,无论多少内存,迟早会被占光。

    不再会被使用的对象或者变量占用的内存空间不能被回收,就是内存泄漏。

    强引用:使用最普遍的一个引用(new),一个对象具有强引用,不会被垃圾收集器回收。当内存空间不足,java虚拟机宁愿OOM,都不会回收。

    如果想取消强引用和某个对象之间的关联,可以显示将对象复制为null,这样jvm就会在安全区域执行gc进行垃圾回收。

    弱引用:jvm进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用WeakReference类来表示。

    ThreadLocal的实现原理,每一个Thread维护一个ThreadLocalMap,ThreadLocalMap是由一个个Entry构成,而Entry继承了弱引用,key为使用弱引用的ThreadLocal对象,value为线程变量的副本。


    ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal不存在外部的强引用时,Key(ThreadLocal对象)势必会被GC回收,这样就会导致ThreadLocalMap中的key为null,而value还存在着强引用,只有thread线程退出以后,value的强引用链才会断掉,但是如果线程迟迟不结速的话,这些key为null的Entry的value就会一直存在引用链。

    key使用强引用
    当ThreadLocalMap的key使用强引用时,此时若是外部的ThreadLocal对象被置为null,按理说应该被回收,但是ThreadLocalMap中还持有对ThreadLocal的强引用,如果没有手动删除,那么ThreadLocal不会被回收,导致Entry内存泄漏。

    key使用弱引用
    当ThreadLocalMap的key为弱引用回收ThreadLocal对象时,由于ThreadLocalMap只持有ThreadLocal的弱引用,即使没有手动删除,也不会影响ThreadLocal的回收。当key为null时,在下一个调用ThreadLocalMap的set、get、remove方法时会清除value值。

    ThreadLocal正确使用方法

    • 每次使用完ThreadLocal都调用它的remove方法清楚数据
    • 将ThreadLocal变量定义为private static,这样就一直存在ThreadLocal的强引用,也就能保证在任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,继续清除。
  • 相关阅读:
    4.JDBC编程
    android 多线程
    android 网络请求Ⅰ
    android 数据存储Ⅱ
    android 数据存储Ⅰ
    android 界面设计基本知识Ⅳ
    《将博客搬至CSDN》
    android 界面设计基本知识Ⅲ
    android 界面设计基本知识Ⅱ
    android 界面设计基本知识
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/14789750.html
Copyright © 2011-2022 走看看