引用计数法
判断一个对象是否是垃圾.在一个对象被引用时加一,被去除引用时减一
GC Root Tracing 算法
解决引用计数法存在的循环引用问题. 从 GC Root 出发,所有可达的对象都是存活的对象,而所有不可达的对象都是垃圾
GC Root 是一组活跃引用的集合
- 所有当前被加载的 Java 类
- Java 类的引用类型静态变量
- Java类的运行时常量池里的引用类型常量
- VM的一些静态数据结构里指向GC堆里的对象的引用
- 等等
垃圾回收算法
垃圾回收算法简单地说有三种算法:标记清除算法、复制算法、标记压缩算法
标记清除算法
分为两个阶段:标记阶段和清除阶段.
- 标记阶段,标记所有由 GC Root 触发的可达对象.所有未被标记的对象就是垃圾对象
- 清除阶段,清除所有未被标记的对象
会产生内存碎片,但是不需要移动太多对象,比较适合在存活对象比较多的情况
复制算法
将原有的内存空间分为两块,每次只使用一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中。之后清除正在使用的内存块中的所有对象,之后交换两个内存块的角色,完成垃圾回收
需要将内存空间折半,并且需要移动存活对象. 但清理后不会有空间碎片,比较适合存活对象比较少的情况
标记压缩算法
标记压缩算法可以说是标记清除算法的优化版,其同样需要经历两个阶段,分别是:标记结算、压缩阶段。在标记阶段,从 GC Root 引用集合触发去标记所有对象。在压缩阶段,其则是将所有存活的对象压缩在内存的一边,之后清理边界外的所有空间
分代思想
单独采用任何一种垃圾回收算法,效果都不会很好. 因此在实际的垃圾回收算法中采用了分代算法
根据 JVM 内存的不同内存区域,采用不同的垃圾回收算法.
对于存活对象少的新生代区域,比较适合采用复制算法.这样只需要复制少量对象,便可完成垃圾回收,并且还不会有内存碎片
对于老年代这种存活对象多的区域,比较适合采用标记压缩算法或标记清除算法,这样不需要移动太多的内存对象
新生代内存比例分析
新生代内存分为Eden区,from区,to区三个区域. 比例为8:1:1
新生代对象特点是生存时间短,回收发生时是将Eden和Survivor中还存活的对象复制到另一个Survivor空间上. 按默认分配方式,新生代内存利用率为90%.如果仅分配两块内存提供给复制算法使用,利用率为50%.
文章链接 https://fangzongzhou.github.io/2020/11/11/计算机/技术栈/Java/JVM/JVM垃圾回收机制/