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值,继续清除。
  • 相关阅读:
    指针传递的一些必要的记录,避免以后又忘记了。
    记录下这几个FMX控件的地址
    boost.ASIO-可能是下一代C++标准的网络库
    对本程序使用自己的代理服务器
    C# 为网络程序添加用户代理
    InternetOpen怎么使用代理
    改变代理服务器
    在Delphi中,关于数组名称
    Delphi 获取进程路径及命令行参数
    关于在asp.net的web页面中的全局变量问题
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/14789750.html
Copyright © 2011-2022 走看看