JVM垃圾收集机制
整个JVM中的GC的处理机制:对不需要的对象进行标记,而后进行清除.
JDK 1.8之后将最初的永久代内存空间取消了
取消永久代目的:是为了将HotSpot与JRockit两个虚拟机标准联合为一个。
在整个的JVM堆内存之中实际上将内存分为了三块:
- 年轻代:新对象和没达到一定年龄的对象都在年轻代;
- 老年代:被长时间使用的对象,老年代的内存空间应该要比年轻代更大;
-
元空间:像一些方法中的操作临时对象等,直接使用物理内存;
- 最初的永久代是需要在JVM堆内存里面进行划分
GC流程
所有的数据都会保存在JVM的堆内存之中,但是在实际的开发之中经常会创建许多的临时对象,也会有一些常驻对象存在,所以为了保证GC的性能问题,对于GC
的处理流程如下图所示
对于整个的GC流程里面,那么最需要处理的就是年轻代与老年代的内存清理操作,而元空间(永久代)都不在GC范围内;
当现在有一个新的对象产生,那么对象一定需要内存空间,于是现在就需要为该对象进行内存空间的申请;
首先会判断伊甸园区是否有内存空间,如果此时有内存空间,则直接将新对象保存在伊甸园区;
但是如果此时伊甸园区的内存空间不足,那么会自动执行一个MinorGC操作,将伊甸园区的无用内存空间进行清理,清理之后会继续判断伊甸园区的内存空间是否充足?如果内存空间充足,则将新的对象直接在伊甸园区进行空间分配;
如果执行了Minor GC之后发现伊甸园区的内存依然不足,那么这个时候会进行存活区判断,如果存活区有剩余空间,则将伊甸园区的部分活跃对象保存在存活区,那么随后继续判断伊甸园区的内存空间是否充足,如果充足,则在伊甸园区进行新对象的空间分配;
如果此时存活区也已经没有内存空间了,则继续判断老年区,如果此时老年区空间充足,则将存活区中的活跃对象保存到老年代,而后存活区就会存现有空余空间,随后伊甸园区将活跃对象保存在存活区之中,而后在伊甸园区里为新对象开辟空间;
如果这个时候老年代也满了,那么这个时候将产生M ajor GC(FullGC),进行老年代的内存清理。
如果老年代执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError”
那么请思考“StackOverflowError”和“OutOfMemoryError”的区别是什么呢?