回答任何一个问题的时候应该要遵循:明确题意-->深入浅出-->举例说明-->总结,这四个步骤很重要,可以让你沉着冷静,思路清晰,避免尴尬。

01 —  明确题意

明确题意的意思就是先明确一下面试官的题目,能避免自己理解有误而跑题,可以这样说:ThreadLocal内存泄漏的原因主要是因为ThreadLocal中包含了ThreadLocalMap,然而ThreadLocalMap的对象是在Thread中的,如果Thread没有结束,则ThreadLocalMap一直不会释放,假如ThreadLocalMap中设置了很多值,而且没有手动设置remove(),则可能会造成内存泄露。网上有些网友的答案是因为ThreadLocal作为一个弱引用的key然后造成每次GC的时候会回收掉ThreadLocal,导致无法访问value,然后造成了内存泄漏,这是完全错误的,其实和弱引用没有关系。

02 — 深入浅出

先思考一下,如果每次GC都把ThreadLocal给回收掉,那么业务代码在运行的时候出现GC,ThreadLocal被回收之后,业务代码就会获取不到值,这样就会出现问题。弱引用的定义确实是在GC的时候就会被回收掉,如果ThreadLocal又被其它强引用指向了,则它是不会被回收的,想想我们在使用ThreadLocal的时候,我们是怎么定义并使用他的呢?

可以看到threadLocal可以定义为一个全局的静态变量或者是一个局部变量,threadLocal是强引用,不管怎么样它都不会被回收掉,只是又将它的引用又给到了ThreadLocalMap中的Entry.key中,虽然这个key是弱引用,但是ThreadLocal对象是不会被回收的。

如果一个线程Thread结束了,那么Thread里面的threadLocals将会被回收掉,也就是ThreadLocalMap数据结构会被回收掉,也就不会出现内存泄漏的问题。那出现内存泄露的情况是什么呢?

当Thread一直没有结束时,Thread中的threadLocals就不会被回收,threadLocals里面存储的Entry如果不手动删除的话,就会一直存在这个threadLocals里面,所以就会出现内存泄漏的问题,通常在线程池的情况下,一个Thread会使用很长时间,如果在使用的过程中,一直向里面设置Entry,也就是key = ThreadLocal 和 value=业务对象,如果一个线程的任务执行完毕之后,没有手动设置remove()方法释放掉这个Entry的话,那么Thread的threadLocals中的Entry将会一直膨胀,一直停留在Thread中的threadLocals中,造成内存泄漏,所以一定要手动设置remove()。

那这会延伸出来另外一个问题,为什么使用弱引用?

弱引用的作用就是当出现GC的时候会回收这些弱引用的对象,如果有些业务不是定义的全局的静态变量而是局部的变量,例如:通过ThreadLocal保存一些在整个线程中全局都可以使用的变量,减少方法与方法调用的参数传递。此时当一个任务执行完成之后,可以将ThreadLocal设置成为null,局部变量的强引用就会失效,存在Map中的Entry的key只有弱引用,如果不进行清理的话,则会出现内存泄漏的问题,此时出现GC的时候就会回收掉ThreadLocal对象,也就是说ThreadLocal是尽量的去避免内存泄漏的问题。但是解决不了根本的问题,所以需要开发人员手动去调用remove()方法才能够彻底解决内存泄漏的问题。

03 — 举例说明

找到了一个开源项目ruoyi框架的源码,可以看到ThreadLocal是一个全局的静态变量,不同的线程不会影响彼此,ThreadLocal永远不会被回收掉,在线程池的情况下,当我们操作完之后,需要手动调用remove()方法,上图也提供了clearDataSourceType()方法用来清除任务执行完之后的Entry对象。

可以看到在Aspect切面中的around方法中,最终调用了此方法。

04 — 总结

最后来句总结:这就是我对ThreadLocal内存泄漏的理解。主要的作用是提醒面试官说完了,看看面试官是否有问题要问,或者让面试官提问下一个问题,不要让面试官或者自己尴尬。

聊一聊ThreadLocal内存泄漏的问题相关推荐

  1. 深入分析 ThreadLocal 内存泄漏问题

    转载自 http://www.importnew.com/22039.html ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件 ...

  2. 【java】ThreadLocal 内存泄漏 代码演示 实例演示

    1.概述 转载:ThreadLocal 内存泄漏 代码演示 实例演示 首先看文章:ThreadLocal内存泄露原因分析 相关文章: [高并发]ThreadLocal.InheritableThrea ...

  3. 【转载】深入分析 ThreadLocal 内存泄漏问题

    前言 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用 ThreadLocal,就可 ...

  4. ThreadLocal内存泄漏原理解析

    1.什么是内存泄漏问题? 内存泄漏 表示就是我们申请了内存,但是该内存一直无法释放: 内存泄漏会导致内存溢出问题: 申请内存时,发现申请内存不足,就会报错 : 2.在介绍ThreadLocal内存泄漏 ...

  5. ThreadLocal内存泄漏问题

    ThreadLocal可以存取各线程专属的变量副本,底层是通过ThreadLocalMap实现,存的K-V K:WeakReference弱引用 V:变量副本 一旦某线程长期存活,但ThreadLoc ...

  6. Java并发编程笔记之ThreadLocal内存泄漏探究

    使用 ThreadLocal 不当可能会导致内存泄露,是什么原因导致的内存泄漏呢? 我们首先看一个例子,代码如下: /*** Created by cong on 2018/7/14.*/ publi ...

  7. ThreadLocal 内存泄漏问题

    本文说说ThreadLocal由于使用不当造成的内存泄漏问题 Thead和ThreadLocal的内存状况如下图,不了解的同学参考: 图解ThreadLocal核心原理 如果线程太多,每个线程的val ...

  8. 关于ThreadLocal内存泄漏的问题

    什么是ThreadLocal? ThreadLoal 变量,线程实例变量,同一个 ThreadLocal 所包含的对象,在不同的 Thread 中有不同的副本.这里有几点需要注意: 因为每个 Thre ...

  9. c++ thread 内存泄漏_深入剖析ThreadLocal原理、内存泄漏及应用场景

    本文主要针对JDK1.8讲解 ThreadLocal作用 先看一个简单的示例,创建两个线程,第一个线程向ThreadLocal中写入数据,第二个线程等待第一个线程完成从ThreadLocal中读取数据 ...

最新文章

  1. 如何使div填充剩余的水平空间?
  2. 关于开发系统后门软件的几点思路
  3. redis 连接池_SpringBoot整合redis
  4. flume package遇到的问题
  5. EJB3.0学习笔记--第一个EJB程序:
  6. 双机热备、集群及高可用性入门转载
  7. 记一次幸运的拼多多Web前端面试(一面+二面+hr面)
  8. 博士申请 | 香港大学计算机科学系黄超老师招收2022年入学全奖博士生
  9. python重命名异常_Python:如何忽略异常并继续?
  10. WIN10下 搭建golang+vscode开发环境(图文并茂,傻瓜式教程)
  11. eclips 安装问题
  12. KVM远程迁移启动报错
  13. 使用OpenCV调用摄像头检测人脸并截图-Python
  14. 数据库中 PK FK UK CK DF 的意思
  15. 301重定向解决域名被墙教程
  16. 简单假币问题以及复杂假币问题
  17. ES中 must和should并列查询问题
  18. C++ 提取字符串中的所有数字
  19. ios 主题切换 思路_一个轻量级的iOS皮肤切换方案(内附Demo)
  20. 借助Zotero标签功能实现已读功能

热门文章

  1. 计算机 存储体 存储单元 存储元 存储字 存储字长的联系
  2. JVM 下篇:性能监控与调优
  3. html写的代码投屏到LED屏,会议室小间距LED屏可以实现笔记本电脑的无线投屏显示吗?...
  4. 中国地质大学英语语音学习笔记(八):英语重音与重音移位——为发音添彩
  5. 执一不二 跬步千里-王子密码2011年11月份心得(十)
  6. spyder pyecharts不显示_微星PAG272QRZ显示器好不好用 微星PAG272QRZ显示器全面评测_显示器_硬件教程...
  7. 我分析了上万个微信红包数据,得到了这些发现(附数据集)
  8. Composer 基础使用
  9. 牛刀:中国房价的买点还没有…
  10. 使用谷歌浏览器调试PC网页、手机APP