【线程】ThreadLocal 内存泄漏问题(十五)

本文深入探讨了ThreadLocal机制下的内存泄漏问题,分析了泄漏的原因,解释了为何使用弱引用,以及源码层面如何减少泄漏。同时,提供了手动释放资源的方法,以避免内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我的原则:先会用再说,内部慢慢来。
学以致用,根据场景学源码


一、架构图

在这里插入图片描述

=== 点击查看top目录 ===

二、为什么会内存泄漏?

  1. 看下图,当 threadLocal1,threadLocal2,threadLocal3 = null的时候,table中 Entry的引用依然还在。假如thread01,thread02,一直不结束。那么Entry中的引用会一直存在(thread01Ref->Thread01->threadLocalMap01->entry->valueRef->valueMemory), 导致在垃圾回收的时候进行可达性分析的时候,value可达从而不会被回收掉,但是该value永远不能被访问到,这样就存在了内存泄漏。
    在这里插入图片描述
    === 点击查看top目录 ===

三、ThreadLocal的Entry 为什么要用 weakReference ?

  • ThreadLocal.ThreadLocalMap.Entry
public class ThreadLocal<T> {
    
    
	static class ThreadLocalMap {
    
    
		static class Entry extends WeakReference<ThreadLocal<?>> {
    
    
		    Object value;
		    Entry(ThreadLocal<?> k, Object v) {
    
    
		        super(k);
		        value = v;
		    }
		}
	}
}
  • Thread
public java.lang.class Thread implements Runnable {
    
    
	...     
    ThreadLocal.ThreadLocalMap threadLocals = null;
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
    ...
}
  • Thread的 exit 方法
    private void exit() {
    
    
        if (group != null) {
    
    
            group.threadTerminated(this);
            group = null;
        }
        /* Aggressively null out all reference fields: see bug 4006245 */
        target = null;
        /* !!!看这里!!! */
        threadLocals = null;
         /* !!!看这里!!! */
        inheritableThreadLocals = null;
        inheritedAccessControlContext = null;
        blocker = null;
        uncaughtExceptionHandler = null;
    }

Thread#exit方法会把内部的threadLocals设置为 null,threadLocalMap生命周期实际上thread的生命周期相同。

3.1 为什么ThreadLocal不用强引用?
  • 因为weakReference 能够一定程度上避免内存泄漏

当Thread一直存在,threadLocal1,threadLocal2,threadLocal3 = null的时候。GC看到 threadLocal1,threadLocal2,threadLocal3 指向的对象的只有 weakReference 引用的时候,会将

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值