JVM的垃圾回收机制

JVM中的垃圾回收机制:

JVM中的分代模型,根据object对象的存在时间分成了三种代

年轻代、老年代、持久代

年轻代中分为两大空间,Eden和S层(也就是存活层),存活层S分为两部分S0、S1.
官方建议年老代是年轻代的两倍

JVM的垃圾回收机制_第1张图片

年轻代的object对象要到年老代的三种方式:

  1. object对象经历了默认的15次GC还在活跃就会被移动到年老代
  2. object对象超出设置的参数也会被移动到年老代
  3. 当存活区中有一个区中活跃的object充满了这个区,那么这个区中的所有object对象都会被移动到年老代

刚创建的对象大部分会存放在Eden中,当Eden中的内存要满了之后,就会发生一次full GC,将Eden中的不活跃的对象,也就是没有再用到的对象给销毁,将还在用到的object对象给移动到存活区S0。此时Eden和S1是空的,然后再第二轮再创建对象继续GC,将Eden中和存活区S0中的对象移动到S1,然后此时Eden和S0都是空的,S1中都是还在活跃用到的对象。这就是著名的“停止复制”算法

然后当object中对象在经历了15次full GC的时候(这个是JVM中默认设置的一个参数),就会被移动到老年代,当object中的对象足够大的时候也会被移动到老年代,老年代的object如果要被销毁的话,是要先标记-再销毁的。老年代的空间的容量要比年轻代的空间容量要大,而且老年代GC的次数也会比年轻代GC的次数要少的多。

如果老年代中要加入的一个object对象大小大于此时老年代中的存储空间的话,也会发生一次GC。

老年代中会维护一个512byte的块,存放的是老年代要引用的年轻代中的object,若老年代中的object对象要用到年轻代中的object对象,当young GC的时候,只会遍历这里,就不会遍历老年代的object对象了

持久代中存放常量池,静态常量,可序列化的对象等。

当发生一次full GC的时候,也会销毁掉持久代中的可销毁的对象。

可销毁的对象:也就是遍历root节点,从上往下遍历这颗树,如果找到没有连接的object对象,那么这个对象就是可被销毁的。

JVM的垃圾回收机制_第2张图片

这里面的红色部分就是可以被销毁的object对象。


以上部分是JDK1.7以前的版本

方法区中存放常量池、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法。平常人们将永久带和方法区是等同的。但是方法区是标准,永久带是实现。这就相当于你将Java中的接口和接口的实现等同对待了一样。

接下来说JDK1.8之后的版本(包含JDK1.8)

JDK1.8之后将永久带给移除了,用新出现的元空间来代替了永久带。因为永久带用到的是内存,而元空间用到的是本地磁盘,这样更加安全

你可能感兴趣的:(JAVA,JVM)