图解 Java 垃圾回收机制,写得非常好

什么是自动垃圾回收?
自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制 。
所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象;而未使用中的对象(未引用对象),则没有被任何指针给指向,因此占用的内存也可以被回收掉 。
在用 C 之类的编程语言时,程序员需要自己手动分配和释放内存 。而 JAVA 不一样,它有垃圾回收器,释放内存由回收器负责 。本文接下来将介绍垃圾回收机制的基本过程 。
第一步:标记
垃圾回收的第一步是标记 。垃圾回收器此时会找出哪些内存在使用中,还有哪些不是 。

图解 Java 垃圾回收机制,写得非常好

文章插图
 
上图中,蓝色表示已引用对象,橙色表示未引用对象 。垃圾回收器要检查完所有的对象,才能知道哪些有被引用,哪些没 。如果系统里所有的对象都要检查,那这一步可能会相当耗时间 。关注Java技术栈微信公众号,回复:JVM46,可以获取一份超全 JVM 调优攻略 。
第二步:清除
这一步会删掉标记出的未引用对象 。
图解 Java 垃圾回收机制,写得非常好

文章插图
 
内存分配器会保留指向可用内存的引用,以供分配新对象 。
压缩
为了提升性能,删除了未引用对象后,还可以将剩下的已引用对象放在一起(压缩),这样就能更简单快捷地分配新对象了 。
图解 Java 垃圾回收机制,写得非常好

文章插图
 
为什么需要分代垃圾收集?
之前说过,逐一标记和压缩 Java 虚拟机里的所有对象非常低效:分配的对象越多,垃圾回收需时就越久 。不过,根据统计,大部分的对象,其实用没多久就不用了 。JVM 与 linux 的内存关系详解,这篇推荐阅读 。
来看个例子吧 。(下图中,竖轴代表已分配的字节,而横轴代表程序运行时间)
图解 Java 垃圾回收机制,写得非常好

文章插图
 
上图可见,存活(没被释放)的对象随运行时间越来越少 。而图中左侧的那些峰值,也表明了大部分对象其实都挺短命的 。
JVM 分代
根据之前的规律,就可以用来提升 JVM 的效率了 。方法是,把堆分成几个部分(就是所谓的分代),分别是新生代、老年代,以及永生代 。JVM运行时区域详解,这篇推荐大家看下 。
图解 Java 垃圾回收机制,写得非常好

文章插图
 
新对象会被分配在新生代内存 。一旦新生代内存满了,就会开始对死掉的对象,进行所谓的


    推荐阅读