目录
- 1- 引言:垃圾回收
- 1-1 什么是垃圾回收?(What)
- 1-2 为什么要进行垃圾回收?(Why)
- 2- ⭐核心:对象什么时候可以被垃圾回收器回收?(How)
- 2-1 对象什么时候可以被回收?
- 2-2 引用计数法
- 引用计数法存在的问题:循环引用——>内存泄漏
- 2-3 可达行分析算法
- 哪些对象可以作为 GC Root?
- 3- 小结
- 3-1 什么是垃圾回收?为什么要进行垃圾回收?
- 3-2 对象什么时候可以被垃圾回收?
- 3-3 哪些对象可以作为 GC Root?
1- 引言:垃圾回收
1-1 什么是垃圾回收?(What)
- Java的垃圾回收(Garbage Collection, GC)是Java虚拟机(JVM)自动管理内存的一种机制。它的主要目的是自动回收不再使用的对象所占用的内存,以防止内存泄漏和优化内存使用。
1-2 为什么要进行垃圾回收?(Why)
- 垃圾回收是对于 Heap 堆 而言的,我们创建的对象或数组一般都是在 Heap 堆中。我们不能无限制的创建对象,同时不是所有对象都是需要一直存活,如果不进行垃圾回收,则内存迟早会被耗尽,因此及时的垃圾回收是有必要的。
2- ⭐核心:对象什么时候可以被垃圾回收器回收?(How)
2-1 对象什么时候可以被回收?
- 如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收。
- 如果要定位什么是垃圾,有两种方式来确定,第一个是 引用计数法,第二个是 可达性分析法。
2-2 引用计数法
- 一个对象被引用了一次,在当前对象投上递增一次引用次数,如果这个对象的引用次数为 0 ,嗲表这个对象可以回收。
- 例如对于
new String("123")
,而言最初的 demo 对于 其的 引用ref = 1
,在执行了demo = null
之后 其对应的ref = 0
,此时的结果 是可以被垃圾回收的。
引用计数法存在的问题:循环引用——>内存泄漏
- 如果对象之间出现了循环引用的话,则引用计数法就会失效。
- 比如 a 和 b 对象的成员变量,分别又引用对法。
- 此时执行到了 a = null,b = null 的时候 a 和 b 实际上是没有人使用的,而此时二者的引用计数都为 1
- 此时二者都不会被回收,会出现循环引用的问题,导致内存泄漏
2-3 可达行分析算法
- 现在的虚拟机采用的都是可达行分析算法来确定哪些内容是垃圾。
X,Y 这两个结点是可回收的
- Java 虚拟机中的垃圾回收器采用可达行分析来探索所有存活的对象。
- 扫描堆中的对象,看是否可以沿着 GC Root 对象为起点的引用链找到该对象,找不到表示可以回收。
哪些对象可以作为 GC Root?
- ①虚拟机栈(栈帧中的本地变量表)中引用的对象。——> 对于第一个
Demo demo = new Demo()
可以作为 GC Root。 - ②方法区中类静态属性引用的对象。——> 对于第二个 b.a = new Demo(); 其中 a 可以作为 GC Root。
- ③方法区中常量引用的对象。——> 对于第三个方法区中的常量可以作为 GC Root。
- 本地方法栈中 JNI (即一般说的 Native方法)引用的对象。