JVM运行时数据区是一种规范,JVM内存模型是对该模型的实现。
JVM内存模型分为:堆和非堆。
堆分为:Old区、young区,比例为2:1。
young区分为:Eden 区、 ServivorFrom、 ServivorTo 三个区。比例为8:1:1
Eden:Java新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老年代)。当 Eden区内存不够的时候就会触发 MinorGC,对新生代区进行一次垃圾回收。
ServivorFrom:上一次 GC 的幸存者,作为这一次 GC 的被扫描者。
ServivorTo:保留了一次 MinorGC 过程中的幸存者。
注意:from和to区始终有一块是不使用的(空的)。
MinorGC 采用复制算法。
MinorGC执行过程:首先把Eden和from区中存活的对象复制到to区(如果对象的年龄达到老年代的标准,则直接复制到老年代中,这个年龄默认是15),同时把这些对象的年龄+1(如果to区内存不够就放到老年区)。然后清空Eden和from区。最后to区和from区互换,原来的to区成为下一次GC时的from区。
Old区:老年代的对象比较稳定,所有MajorGC不会频繁执行。在进行MajorGC之前一般都先进行一次MinorGC。当无法找到足够大的连续空间分配给创建较大对象时也会提前触发一次MajorGC进行垃圾回收腾出空间。
MajorGC采用标记清除算法。
MajorGC执行过程:首先扫描一次所有老年代,标记处存活对象,然后回收没有标记的对象。MajorGC需要扫描回收所以耗时比较长。MajorGC会产生内存碎片,为了减少内存损耗,一般需要进行合并或者标记出来方便下次直接分配。