JVM之垃圾回收

JVM将内存划分为新生代和老年代,新生代包含Eden区和两个Survivor区,通过MinorGC清理短生命周期对象。老年代存放长生命周期对象。卡表用于追踪跨代引用,提高GC效率。

  Java对象的存活周期也满足二八定律,也就是说,大约有80%左右的对象生命周期很短,需要将他们及时的清理掉,而仅仅20%左右的对象存活周期比较长,进行垃圾回收的时候,就需要注意。

  根据对象存活周期的规律,JVM将内存划分为了新生代和老年代,新生代对应存活周期短的对象,老年代对应存活周期比较长的对象。

  新生代又划分为Eden区和两个大小相同的Survivor区,由from指针和to指针维护。两者之间的内存分配比率默认是随机分配,也可以通过参数固定。

  新分配的对象都在Eden区,如果Eden区满了,就会触发Minor GC,存活下来的对象会被复制到from指针的Survivor区,然后from指针和to指针交换位置,保证to指针内存空间为空。

  在Survivor区复制超过15次的对象会被提升到老年代,因为负责计数标志只有四位。或者当Survivor区内存使用率超过50%,也会将复制次数比较高的对象提升到老年代。

  如果有老年代对象对新生代对象的引用,GC时为了避免全堆扫描,利用卡表计数解决这个问题。HotSpot虚拟机将对内存划分为512字节的表,利用一张卡表来记录这张表内是否有老年代想新生代的引用,有的话,将这张表标记为脏表。

  在进行Minor GC的时候,就不用进行全堆扫描,只扫描卡表,监测到脏表的时候,将标志位清除。对新生代GC之后,会对存活的对象进行复制操作,这个时候,会再次设置该部分内存的脏卡标志。

  这也会带来两个问题:
  1. 无条件写屏障的性能开销。
  这个开销相比与全堆扫描的性能开销来说,是可以接受的。

  2. 高并发下虚共享带来的性能开销。
  这个会先判断卡页的标志位是否已经标记过了,如果已经标记过了,就不再进行标示。

参考资料:
JVM之卡表(Card Table)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值