一、什么是自动垃圾收集?
自动垃圾收集是在堆内存中找出没用对象并删除的过程。
步骤1:标记
这一步是垃圾收集器识别出哪块儿内存是有用的、哪些内存是没用的。
image蓝色标记的是有用的对象,黄色标记的没有被引用的对象。
所有对象扫描一遍是非常耗时的过程。
步骤2:常规删除
删除没有被引用的对象,留下被引用对象,并记录下空余空间,内存分配器持有一个空闲空间列表,当有分配空间的需求时,从列表中找出合适的进行分配。
image步骤2a:删除并压缩
为了提升性能,删除没用的对象之后,把留下的那些对象移动到一起,这样可以使新的内存分配更简单快速。
image二、为什么要使用分代的垃圾回收?
如上所述,对所有对象执行标记、删除、压缩这套流程是非常低效的。因为分配的对象越来越多,对象列表越来越大,导致垃圾回收所花费的时间越来越长。
实践证明,绝大多数对象的存活时间都是很短的。
image这是一个统计图,Y轴显示分配的字节数,X访问显示随着时间的推移分配的字节数。可以看到,随着时间的推移,越来越少的对象存活下来。
JVM 分代
上面的统计可以帮助我们提升JVM的性能,可以把堆空间分为多个部分(称为代),包括:年轻代、老年代、持久代。
image- 年轻代(Young Generation)
新创建的对象都分配到这个空间,这个空间不足之后就会执行 minor gc(年轻代垃圾回收),大部分无用对象被清除,一些存活对象被移至老年代。
Stop the World - minor gc 都是 ”stop the world“ 事件,意味着所有应用线程都要停下来,直到垃圾收集完成。
- 老年代(Old Generation)
存放存活时间长的对象。
对象的存活时间有一个阈值,当年轻代中的对象的年龄达到条件后,就转移到老年代。
老年代的垃圾收集叫做 major gc,major gc 也是 ”stop the world“ 事件。
- 持久代(Permanent generation)
存放一些元数据,例如类、方法的描述信息。
类也是可以被卸载的,比如JVM发现他不再被使用,并且其他类需要空间。
full gc 会对所有空间进行垃圾回收,就包括持久代。
文档地址:
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
网友评论