(三)【Java精选面试题】Threadlocal内存泄漏问题(含答案)


1. 谈谈你对 Threadlocal 理解?

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

Threadlocal 基本 API
1.New Threadlocal();—创建 Threadlocal
2.set 设置当前线程绑定的局部变量
3.get 获取当前线程绑定的局部变量
4.remove() 移除当前线程绑定的变量

2. 哪些地方有使用 Threadlocal

1.Spring 事务模板类
2.获取 HttpRequest
3.Aop 调用链

3. Threadlocal 底层实现原理

  1. 在每个线程中都有自己独立的 ThreadLocalMap 对象。
  2. 如果当前线程对应的的 ThreadLocalMap 对象为空的情况下,则创建该ThreadLocalMap对象,并且赋值键值对。
    Key 为 当前 new ThreadLocal 对象,value 就是为 object 变量值。
    在这里插入图片描述

4. 为什么线程缓存的是 ThreadlocalMap 对象

ThreadLocalMap 可以存放 n 多个不同的 ThreadLocal 对象;
每个 ThreadLocal 对象只能缓存一个变量值;

ThreadLocalMap<ThreadLocal 对象,value> threadLocalMap
ThreadLocal.get();
threadLocalMap.get(ThreadLocal)-----缓存变量值

5. 谈谈强、软、弱、虚引用 区别

强引用: 当内存不足时,JVM 开始进行 GC(垃圾回收),对于强引用对象,就算是出现了OOM 也不会对该对象进行回收,死都不会收。

软引用:当系统内存充足的时候,不会被回收;当系统内存不足时,它会被回收,软引用通常用在对内存敏感的 程序中,比如高速缓存就用到软引用,内存够用时就保留,不够时就回收。

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

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

6. Threadlocal 为何引发内存泄漏问题

补充概念:
什么是内存泄漏问题
内存泄漏 表示就是我们程序员申请了内存,但是该内存一直无法释放;
内存泄漏溢出问题:
申请内存时,发现申请内存不足,就会报错 内存溢出的问题;

因为每个线程中都有自己独立的 ThreadLocalMap 对象,key 为 ThreadLocal,value 是为变量值。

Key 为 ThreadLocal 作为 Entry 对象的 key,是弱引用,当 ThreadLocal 指向null 的时候,Entry 对象中的 key 变为 null,GC 如果没有清理垃圾时,则该对象会一直无法被垃圾收集机制回收,一直占用到了系统内存,有可能会发生内存泄漏的问题。

7. 如何防御 Threadlocal 内存泄漏问题

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

8. Threadlocal 采用弱引用而不是强引用

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

2.如果 key 是为弱引用:
当我们现在将 ThreadLocal 的引用指向为 null,Entry 中的 key 指向为null,但是下次调用 set 方法的时候,会根据判断如果 key 空的情况下,直接删除,避免了Entry 发生内存泄漏的问题。

3.不管是用强引用还是弱引用都是会发生内存泄漏的问题。
弱引用中不会发生 ThreadLocal 内存泄漏的问题。

4.但是最终根本的原因 Threadlocal 内存泄漏的问题,产生于 ThreadLocalMap 与我们当前线程的生命周期一样,如果没有手动的删除的情况下,就有可能会发生内存泄漏的问题。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级码里喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值