关于ThreadLocal的学习心得及相关补充(垃圾回收机制等)

简单梳理ThreadLocal的作用和底层原理

作用:ThreadLocal主要用于数据隔离。(在ThreadLocal中填充的数据只属于当前线程,相对于其他线程而言是相对隔离的。)

底层实现原理:ThreadLocal会为每个线程创建其对应的副本,线程会访问该副本。ThreadLocal类底层有一个ThreadLocalMap类,使用key-value键值对的形式存储每个线程的副本。key对应当前线程的ThreadLocal对象,value即为对应的副本变量。

但需要注意的是,ThreadLocal中的key属于弱引用,可能会被当成垃圾进行回收,造成一些ThreadLocalMap中一些key为null的键值对。key值为null,那么就无法访问存储的副本数据。如果我们不进行手动删除,那么这一块内存既无法回收也无法访问,这样会造成内存泄漏。所以在使用完ThreadLocal之后,要调用remove方法释放内存。

到这里又有了两个疑惑:

1、那么什么是弱引用,还有其他的类似的引用吗?

2、什么是垃圾回收机制?

相关补充:

1、四种引用类型:强引用、软引用、弱引用、虚引用(理解较浅)

强引用:我们平常使用的大多数类都是强引用。强引用的对象是不会被垃圾回收器回收的。当内存空间不足是,Java虚拟机(JVM)是不会随意回收具有强引用的对象来解决内存不足的问题,甚至JVM会让程序异常终止。

软引用:如果内存空间足够,垃圾回收器就不会回收软引用的对象,如果内存空间不足,就会对软引用的对象进行回收。由此可见软引用的对象处于可有可无的地位。

弱引用:只有弱引用的对象拥有更短的生命周期。垃圾回收器扫描时,只要发现了弱引用的对象,不管内存是否足够,都会将该对象回收。

虚引用:如果一个对象仅有虚引用,那么它就是形同虚设,在任何时候都有可能被回收。

2、垃圾回收机制

如何判断内存中的垃圾?

判断内存中的垃圾主要用两个方法:引用计数法和可达性分析法

引用计数法:当一个对象被创建并进行实例化时,我们可以引入一个计数器,并计数为1。当有其他对象引用此对象的时候,为此对象的计数加一;如果实例化对象失效,那么计数器的数值变为0.当计数器的计数为0时,JVM就会检测到该对象失效,判断该对象为内存中的垃圾并进行回收,释放占用的内存空间。

可达性分析法:可达性分析法也可称为根搜索法。一个对象只有两种状态即可达和非可达,当一个对象至少被一个程序中的变量引用,那么称该对象是可达的。(在引用链中的对象都是可达的,引用链中有根对象从根对象开始向后搜索,如果一个对象没有通过引用链和根对象相连,那么这个对象就是不可达对象)。

如何进行垃圾回收?(垃圾回收算法)

标记-清除算法:为了解决引用计数法的问题提出,分为“标记”和“清除”两个阶段,先标记出需要回收的对象,标记完成之后统一回收掉所有被标记的对象。

另有标记-整理算法、复制算法、分代收集算法待学习补充。

具体学习博客参考:(1条消息) 深入理解 JVM 垃圾回收机制及其实现原理_CG国斌的博客-CSDN博客_jvm 垃圾回收机制

上一篇:【多线程与高并发】4-AQS&强软弱虚


下一篇:ThreadLocal原理及使用场景