Java中堆相关的介绍

92 阅读2分钟

1.概述

Java中的堆对象相对于进程而言是独立的,也就是说一个进程对应一个堆。
堆空间可以是物理上不连续的内存,但是在逻辑上必须连续。
堆空间中允许一部分内存为线程私有,以避免并发问题。
在堆中的对象,当栈帧结束以后,这个对象不会马上移除而是等待垃圾回收机制的执行GC,原因呢主要还是堆中的回收,操作时间太长并且STW。因此需要避免频繁GC,太耗性能了。 关键是记住,对象通常是存在于堆中的。特殊的情况见前文的逃逸分析部分

2.堆的内存结构

  • 新生代
    在这个空间中,分为伊甸园区和S0区S1区,各自的比例默认分配为8:1:1
  • 养老区
    在新生代中的对象年龄超过15的对象会进入养老区,一般情况下这个地方存储的就是不断经过筛选以后还留下的对象,默认新生代和养老区的比例为1:2。
  • 元空间(方法区的具体实现)

3.对象的换区存储的过程

首先对象先进入伊甸园区,当伊甸园区存储满了以后,会进行一次MinGc,会把存活的对象移动到S0区,之后当伊甸园区再次满的时候,会继续触发一次MinGc。这个回收过程会检测伊甸园区和S0区,这两个区域存活的对象会移动到S1区。也就是说,此时S0区涉及到了一次被动的GC回收。当一个对象经历的MinGC次数超过15次的时候,这个对象就会移动到养老区进行存储。
特殊情况:

  • 在移动到S0区的时候,S0区已经满了的时候,这个区域的对象会全部直接移动到养老区
  • 如果一个对象所占据的空间较大,伊甸园区无法继续存储了。那么这个对象会直接存储到养老区

4.MinorGC,MajorGC,FullGC

  • MinorGC:发生在新生代区域中
  • MajorGC:发生在老年代区域中
  • FullGC:发生在新生代、老年代、方法区三个区域中。 补充一个MixGC,这个垃圾回收的发生位置是新生代和部分老年代的区域 以上三种GC方式发生的时机分别是,伊甸园区满的时候触发MinorGC,当老年代满的时候会触发一MinorGC,之后如果还是不够才会触发MajorGC,FullGC的触发机制分别是,老年代空间不足、元空间空间不足、System.GC().