原 《深入理解java虚拟机:jvm高级特性与最佳实践》笔记——Java 的垃圾回收机制

Java的垃圾自动回收,极大的简化了程序开发的复杂度,程序员不再关心内存回收,全部交由虚拟机管理。要理解gc的机制需要知道jvm对于对象处理都是以引用的形式出现的,也就是说,所有的内存访问,都是通过一个或者多个引用进行实际对象内容的访问的。例如本地方法栈就是通过reference存储引用信息(另一块内存的起始地址)进行对象访问的。了解到这个,我们来看一下
Gc被回收对象标记的两大算法:
1、 引用计数法:这个算法很简单,就是在对象中增加一个计数器,有其他的地方引用就加1,引用失效就减1,虚拟机回收所有因为计数器为0 的对象。这个算法实现简单,效果也不错,但是很难解决循环引用问题,也就是闭环式的引用:比如有两个对象,objA和objB,A中有个变量objA.b = objB; objB.a = objA;
public class TestGC {
public TestGC instance ;
public static void main(String[] args){
TestGC objA = new TestGC();
TestGC objB = new TestGC();
objA.instance = objB;
objB.instance = objA;

}

实际工作中可能比这个复杂,比如a –>b->c->d->…->a,引用计数无法对这种引用进行清零,就不能进行回收。目前jvm不适用此种算法。
2、 根搜索法:基本思路就是从一个根对象(gc roots) 作为起点,向下通过reference地址的引用进行搜索,所走过的路径叫做引用链,当对象不在任一引用链上,则进行回收。这就解决了循环引用的问题,因为循环引用无法挂入根对象的引用链上。
在这里插入图片描述
g,h,i虽然有引用,但因为gc roots不可达,依然会被回收。
但一边的标记是分两次的,第一次标记后筛选,是否执行finalize方法,如果没有,则调用,但执行线程等级较低,而且是一部执行,不会等待其结果,如果执行过,则进行回收。如下:
在这里插入图片描述
Gc roots 有以下四种:
1、 Java栈中栈帧中的本地变量表:也就是我们平时程序执行需要的非静态变量
2、 方法区中的类静态属性
3、 方法区中的常量
4、 本地方法栈中的JNI(即native方法):jvm运行所需要的对象。
一般我们默认垃圾回收发生在java的堆中,但其实方法区(也就是永久代)也存在垃圾回收,但是因为“性价比”比较低,而且目前对于类的动态加载场景比较多,所以一般不启用。永久代清理废弃常量和无用的类两种(所有实例被回收并且加载器被回收并且无法被反射访问)。
了解了jvm的标记过程,后面要看一下他的回收算法。
常用的回收算法如下:
1、 标记-清除算法:基本思路是,首先通过标记算法标记出所有的要回收对象,然后所有标记完成后统一进行回收清除。这种是最基础的算法,简单实现,但是效率比较低,而且会产生大量的碎片空间,(大对象无法在连续的碎片空间分配)导致系统频繁gc。
2、 复制算法:基本思路是将内存空间划分两份,每次只用其中一份,当gc触发时,将存活的对象从一个区域复制到另外一个区域中。这个实现比较简单,运行效率高但是内存利用率比较低。
3、 标记-整理算法:基本思路是,将将对象标记以后,让所有仍然存活的对象向一端移动,然后清理掉端边界以外的内存。
4、 分代收集:在不同时期,使用相应的收集算法。如新生代用复制算法,老年代用标记-整理算法。新生代的基本思想是Eden和survivor空间其中一块同时使用,然后gc时同时将存活的对象复制到另一块survivor空间。假如空间不够,则通过内存的分配担保(额度是之前每次写入的平均值),直接进入老年代。一般比例为(Eden) 8:(survivor)1

这地方需要一个注意点,收集器实现上,大部分把minor gc 也就是新生代的gc 设计成并发的,无需停顿,或者只需要停顿小段时间就可以了,而full gc 也就是老年代的gc 设计成单线程清理,需要用户线程等待gc完成后才能继续运行。

另外,对于内存分配上,对象优先在Eden区中,第一次minor gc后进入survivor半区,后续minor gc会不断地在survivor区中来回复制,当经过了一个阈值(15次)后,对象进入老年代,而大对象也会直接进入老年代。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值