一文带你深入JAVA GC(垃圾回收机制)面试讲解!!! - 知乎
gc常用算法
gc常用算法有:标记-清除算法,标记-压缩算法,复制算法,分代收集算法。
复制算法(Java中新生代采用)
缺点:
- 复制算法的代价是将系统内存折半,一般情况下很难让人接受。
- 对于存活对象较多的情况,效率不能保证
标记清除法(Mark-Sweep)
缺点:
标记清除算法回收后的控件时不连续的,会产生空间碎片,在对象的堆空间分配过程中,尤其是大对象的分配,不连续内存空间的工作效率要低于连续的空间。
目前主流的JVM(HotSpot)采用的是分代收集算法。
gc的对象
需要进行回收的对象就是已经没有存活的对象,判断一个对象是否存活常用的有两种办法:引用计数和可达分析。
(1)引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。
(2)可达性分析(Reachability Analysis):从gc roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到gc roots没有任何引用链相连时,则证明此对象是不可用的。不可达对象。
标记压缩清除法(Java中老年代采用)
分为三个阶段:标记阶段,压缩阶段,清除阶段
标记阶段和清除阶段不变,只不过增加了一个压缩阶段,就是在做完标记阶段后, 将这些标记过的对象集中放到一起,确定开始和结束地址,比如全部放到开始处,这样再去清除,将不会产生磁盘碎片。
压缩阶段占用了系统的消耗,并且如果标记对象过多的话,损耗可能会很大,在标记对象相对较少的时候,效率较高。
gc在什么时候,对什么东西,做了什么事情。
在什么时候?
程序员不能具体控制时间,系统在不可预测的时间调用System.gc()函数的时候
对什么东西?
从GC Roots搜索不到,而且经历过一次标记清理之后仍然没有复活的对象。
GC Roots都有哪些:
1.虚拟机栈中的引用的对象
2.方法区中静态属性引用的对象
3.常量引用的对象
4.本地方法栈中JNI(即一般说的native方法引用的对象
做什么?
新生代:复制清理;
老年代:标记-清除和标记-压缩算法
永久代:存放Java中的类和加载类的类加载器本身
- Major GC 是清理老年代。
- Full GC 是清理整个堆空间—包括年轻代和老年代。