ThreadLocal内存泄漏问题

一、对ThreadLocal的理解

  • ThreadLocal提供了线程本地变量,它可以保证访问到的变量属于当前线程,每个线程都保存有一个变量副本,每个线程的变量都不同。
  • ThreadLocal相当于提供了一种线程隔离,将变量与线程相绑定。
  • ThreadLocal适用于多线程的情况下,可以实现传递数据实现线程隔离。

二、ThreadLocal基本API

  1. new ThreadLocal() -----创建ThreadLocal
  2. set设置当前线程绑定的局部变量
  3. get获取当前线程绑定的局部变量

三、哪些地方使用ThreadLocal

  1. Spring事务模板类 (设计模式的模板方法)
  2. 获取httprequest
    SpringMVC获取httprequest对象,SpringMVC封装将httprequest对象缓存在ThreadLocal当前线程中,
  3. Aop拦截请求

四、ThreadLocal 底层实现原理

  1. 在每个线程中都有自己独立的ThreadLocalMap对象,Entry对象。
  2. 如果当前线程对应的ThreadLocalMap对象为空的情况下,则创建ThreadLocalMap对象,并赋值键值对。
  3. key为当前new ThreadLocal对象,value为object变量值。

ThreadLocal 中set方法与get方法源码

public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}



public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
        }
    }
return setInitialValue();
}

五、为什么线程缓存的是ThreadLocalMap对象

  • ThreadLocalMap可以存放多个不同的ThreadLocal对象;
  • 每个ThreadLocal对象只能缓存一个变量值。
  • ThreadLocalMap <ThreadLocal,value> threadLocalMap = new ThreadLocalMap(this, firstValue);
    this代表当前线程ThreadLocal;

六、强、软、弱、虚引用的区别

1. 强引用

当内存不足时,JVM开始进行GC(垃圾回收),对于强引用对象,就算是出现了OOM(Out of memory, 内存溢出)也不会对该对象进行回收,死都不回收。
在这里插入图片描述

2. 软引用

当系统内存充足的时候,不会回收;当系统内存不足时,他会被回收,软引用通常用在对内存敏感的的程序中,比如高速缓存就用到软引用,内存够用时就保留,不够时就回收。
在这里插入图片描述

3. 弱引用

弱引用需要用到java.lang.ref.WeakReference类来实现,它比软引用的生存周期更短。对于只有弱引用的对象来说,只要有垃圾回收,不管JVM的内存空间够不够用,都会回收该对象占用的内存空间。
sql使用弱引用
在这里插入图片描述

4. 虚引用

虚引用需要用java.lang.ref.PhantomReference类来实现,虚引用就是形同虚设。与其他几种引用不同,虚引用并不会决定对象的声明周期。

七、ThreadLocal 如何引发内存泄漏问题

1. 内存泄漏

  • 表示申请了内存,但是该内存一直无法释放。

2. 内存溢出

  • 申请内存时,发现申请内存不足,就会报错内存溢出的问题。

因为每个线程都有自己独立的ThreadLocalMap对象,key为ThreadLocal ,value是为变量值;
key为ThreadLocal 作为entry对象的key,是弱引用,当ThreadLocal 指向null的时候,entry对象中的key变为null,该对象一直无法被垃圾收集机制回收,一直占用到系统内存,有可能会发生内存泄漏的问题。

八、如何防御ThreadLocal 内存泄漏问题

  1. 可以自己调用remove方法将不要的数据移除,避免内存泄漏问题,
  2. 每次在做set方法的时候会清除之前key为null。

九、ThreadLocal 采用弱引用而不是强引用

如果key是为强引用,将ThreadLocal 的引用指向为null,但是每个线程中有自己独立ThreadLocalMap还一直继续持有该对象,但是ThreadLocal 对象不会被回收,就会发生ThreadLocal 内存泄漏问题。

:- 到这里相信你已经get到了
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值