由于GC的分代模型,对Heap进行二次分区
1. 新生代
用来存放新生成的对象,一般占据堆的1/3空间,由于频繁创建对象,所以新生代会频繁的触发GC进行垃圾回收 - MinorGC/YoungGC
1.1 Eden区
Java新生对象的出生地(如果所创建的对象占用内存很大,则直接分配到老年代)。当Eden区内存不够的时候就会触发MinorGC,对Young区进行一次垃圾回收。
1.2 ServivorFrom
用于存放Young区中经过一次MinorGC后的幸存对象
1.3 ServivorTo
与ServivorFrom作用相同,只不过From和To,进行轮换存储,每轮换一次,对象的年龄+1
2. 老年代
用来存放程序中年龄大的内存对象,当老年代达到阈值时会触发MajorGC/FullGC。
- 老年代中的对象都比较稳定,所以MajorGC不会频繁执行
- 在进行MajorGC前一般都先进行一次MinorGC,使得有新生代的对象进入老年代,导致空间不够用时才会触发。当无法找到足够大的连续空间分配给新叉棍见的较大的对象时,也会提前触发一次MajorGC进行垃圾回收
- 当老年代经过MajorGC后,也不能装下目标对象时,系统就会抛出OOM异常(OutOfMemory)
3. 永久代
指内存的永久保存区域,主要存放Class和Meta信息,Class在被加载的时候被放入永久代中,它和存放对象的Heap不同,GC不会在主程序运行期对永久代进行清理。这就会导致永久代的空间随着加载Class的增多而涨满,最终OOM
4. Java8 与 元数据区
Java8中,永久代已经被移除,被元数据区(MetaDataArea)所取代。
元空间的本质与永久代类似,区别在于:元空间不在JVM中,而是使用本地内存,因此默认情况下,元空间的大小仅受本地内存限制。
类的元数据放入NativeMemory中,字符串池和类的静态变量放入Heap中。