欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

对ThreadLocal内存泄漏及弱引用的理解

程序员文章站 2022-03-01 16:53:26
threadlocal内存泄漏及弱引用1.什么是内存泄漏?entry的key弱引用与泄漏关系在treadlocal中内存泄漏是指treadlocalmap中的entry中的key为null,而valu...

threadlocal内存泄漏及弱引用

对ThreadLocal内存泄漏及弱引用的理解

1.什么是内存泄漏?entry的key弱引用与泄漏关系

在treadlocal中内存泄漏是指treadlocalmap中的entry中的key为null,而value不为null。因为key为null导致value一直访问不到,而根据可达性分析,始终有threadref->currentthread->threadlocalmap->entry->valueref->valuememory,导致在垃圾回收的时候进行可达性分析的时候,value可达从而不会被回收掉,但是该value永远不能被访问到,这样就存在了内存泄漏。

因为entry的key是弱引用,所以在gc的时候key会被回收,而value是强引用,导致value不会被回收。

如果不使用弱引用也会可能会发生内存泄漏,只要在业务代码里,将threadlocal的引用置为null,也会导致entry中value访问不到,但又因为可达,所以gc时候不会被回收,相当于这部分内存资源被浪费了

2.为什么entry的key使用弱引用

假设threadlocal使用的是强引用,在业务代码中执行threadlocal instance=null操作,以清理掉threadlocal实例的目的,但是因为threadlocalmap的entry强引用threadlocal,因此在gc的时候进行可达性分析,threadlocal依然可达,对threadlocal并不会进行垃圾回收,这样就无法真正达到业务逻辑的目的,出现逻辑错误。

假设entry弱引用threadlocal,尽管会出现内存泄漏的问题,但是在threadlocal的生命周期里(set,getentry,remove)里,都会针对key为null的脏entry进行处理。

3.预防内存泄漏

threadlocal源码中其实已经对内存泄漏问题做了很多优化,在set,get,remove方法中都会对key为null的但是value不为null的entry进行value置null操作,使得value的引用为null,可达性失败,在gc是可以回收value的内存。

在日常使用中,最后用完treadlocal后,记得remove,为什么呢?

因为如果不remove,当一次gc执行,这个value就会造成内存泄漏直到当前线程结束(线程结束,threalocalmap会被置为null,而threalocalmap中的entry自己也就不可达,会被回收,一切都被回收)

线程结束时会执行thread.exit方法

private void exit() {
    if (group != null) {
        group.threadterminated(this);
        group = null;
    }
    /* aggressively null out all reference fields: see bug 4006245 */
    target = null;
    /* speed the release of some of these resources */
    threadlocals = null;
    inheritablethreadlocals = null;
    inheritedaccesscontrolcontext = null;
    blocker = null;
    uncaughtexceptionhandler = null;
}

匿名内部类会导致内存泄露

内存泄露:就是本该被gc回收的对象,因为各种原因导致的无法被回收,造成内存资源的浪费,从而导致oom。

如果一个类使用了内部类,而两个类的生命周期不一致,比如内部类的生命周期比外部类生命周期长,

这就会导致外部类的生命周期结束了,本该被回收的,却因为内部类会隐式强引用外部类,所以导致外部类无法被回收,

从而造成了内存泄露。

解决方案

1. 可以避免使用内部类;

2. 内部类可以用弱引用来引用外部类;

3. 使用静态内部类,静态内部类不持有外部类的引用(如果要调用外部类方法或使用外部类属性,可以使用弱引用来解决)。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。