本文已参与「新人创作礼」活动,一起开启掘金创作之路。
可达性分析算法
- JVM中的垃圾回收器通过可达性分析来探索所有存活的对象
- 具体是这样的:扫描堆中的对象,看能否沿着GC Root对象为起点的引用链找到该对象,如果找不到,则表示可以回收
哪些对象可以作为 GC Roots 呢?
- 虚拟机栈(栈帧中的本地变量表)中引用的对象。
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(即一般说的Native方法)引用的对象
- 所有被同步锁持有的对象
为什么采用可达性分析而不是引用记数?
- 引用计数虽然简单,但可能发生对象间互相引用而无法被GC的情况,会造成内存泄漏
四种引用是什么?
- 强引用:以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,垃圾回收器不会回收它。
- 软引用:当触发GC时,如果内存空间足够,垃圾回收器就不会回收被软引用(例如softReference)所指的对象,只有当垃圾回收后内存空间不足了才会回收软引用所指的内存。
- 弱引用:当触发Full GC时,无论内存空间足不足够,弱引用所指的对象都会被回收
- 虚引用:如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收。虚引用主要与ByteBuffer使用,当虚引用进入引用队列时,由一个Handler调用虚引用相关方法释放ByteBuffer的直接内存
ps:
- 软引用和弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用弱引用所指的对象被垃圾回收,JAVA 虚拟机就会把这个软引用弱引用本身加入到与之关联的引用队列中,由一个优先级很低的Cleaner进行回收。
- 虚引用必须配合引用队列使用