JVM如何查找垃圾的?
-
Reference Count 引用计数
什么叫RC?
给每一个对象上都标记好有多少个引用,如果当前对象的引用为0,则视为垃圾,应该清除.
像这样的,没有任何引用指向的,就会被清除
很显然,有优点也有缺点
优点是: 容易理解,算法简单
缺点是: 无法清理相互循环引用的大型垃圾 -
Root Searching 根可达
RS是怎么弄的呢?
root searching即从根开始寻找引用,能够找到的则是存活的,否则即为垃圾,这样可以避免相互引用的垃圾无法被清理的情况
说到这那么哪些是GC root呢?
或者这样说
- JVM Stack
- native method stack
- run-time constant pool
- static reference in method area
- 线程栈变量
- 静态变量
- 常量池
- JNI指针
Garbage Collector Algorithms 垃圾回收算法
-
Mark-Sweep (标记清除)
先找到有用和没用的并标记,再把没用的清除掉
存活对象比较多的时候,执行效率会更高,但是容易产生碎片化,两次扫描,效率偏低
垃圾清除完之后
空间不连续,再次分配地址时容易产生不方便 -
Copying (拷贝算法)
将内存区域一分为二,将有用的放在一边,没用的垃圾留在另一边,然后清除
适用于存活对象较少的情况, 容易产生空间浪费,移动复制对象,需要调整对象的引用
当一半的空间快满的时候,进行垃圾回收
先将存活的放在一边
直接清除另外一半的垃圾
-
Mark-Compact (标记压缩)
把所有存活的对象标记,并压缩在一起,清除掉存活对象空间之间的垃圾对象以及空闲空间
将存活的对象放在一块,并清除掉垃圾
经过几步之后:
这种方式不会产生碎片空间,不会产生空间减半,但是同样会需要扫描两次,要移动对象,效率低
我也是才学不久,如果有大佬觉得存在问题,可以在评论区提出哦,谢谢!