JVM——运行时的内存分区
传送门
java堆从GC的角度可以细分为:新生代(Eden区、ServivorFrom 区和ServivorTo区),老年代和永久代(java8中,永久代被“元数据区”(元空间)所取代)。
新生代
用来存放新生的对象。由于要频繁的创建对象,所有会频繁地触发MinorGC进行垃圾回收。新生代分为Eden区(伊甸园)和Servivor区(生存区),Servivor区里边分为ServivorTO区和ServivorFrom区。
-
Eden区
新对象的出生地(如果创建的对象所占空间很大,则直接被分配到老年代)。当Eden区的内存不够时则出发MinorGC,对新生代进行一次垃圾回收。
-
ServivorFrom
上一次GC的幸存者,这一次GC的被扫描者。
-
ServivorTo
保留了一次GC过程中的幸存者。
使用的MinorGC算法:复制算法
老年代
用来存放生命周期较长的对象,通常比较稳定,所以MinorGC不会频繁地执行。当多次MinorGC之后,新生代的一些对象的年龄足够大,晋升为老年代,导致老年代的空间不足时,触发老年代的MinorGC;同样的,若没有足够大的连续空间分配给较大的元素时,也触发MinorGC。
使用的MinorGC算法:标记清除算法或标记整理算法
永久代
指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息。Class 在被加载的时候,被放进永久区域,它和和存放实例的区域不同,GC 不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出OOM异常。Java8 之后被替代。
元空间(元数据区)
Java8中用来替代永久代的区域,本质和永久代了类似,但是,元空间并不在虚拟机中,它使用的是本地内存。因此元空间的大小仅受本地空间的影响。