初识 Java 垃圾回收

Java 和 C++ 之间有一堵内存管理围成的高墙,墙外的人想进去,墙里的人想出去!

什么是垃圾回收

Java 不需要手动管理内存,对象的分配都由 JVM 帮我们完成,不用自己申请内存。既然申请了内存,自然就要释放内存,释放内存的过程就是垃圾回收。

为什么要垃圾回收

随着程序的运行,内存中实例对象和各种变量会越来越多,占用的内存会越来越大,内存容量是有上限的,如果不进行垃圾回收,内存最后肯定不够,然后导致程序崩溃。

怎么回收垃圾

这个问题分以下两方面

  • 确定可回收对象
  • 执行垃圾回收逻辑
确定可回收对象
  • 引用计数法

给每个对象添加一个引用计数器,每被引用一次,计数器加 1,失去引用,计数器减 1。当一段时间内引用计算器为 0 ,这个对象就可以被回收了。但这个方式存在一个很明显的缺陷,不能解决相互引用的问题。

  • 根搜索算法

从一个叫 GC Roots 的对象开始,向下搜索,如果一个对象不可达,则判定为可回收对象。
初识 Java 垃圾回收
因为对象状态是可变的,所以不会直接回收,会给一定的观察期,然后再回收。人非圣贤孰能无过,万一这个对象还能自我拯救,比如重写了 finalize() 就可以实现自我拯救,不建议在程序里面玩这种操作的,会带来安全隐患的。自我拯救方法有很多,这里就不一一介绍了。

执行回收逻辑
  • 标记-清除算法

如同它的名字一样,算法分为「标记」和「清除」两个阶段,首先标记出所有需要回收的对象,在标记完成过后统一回收所有被标记的对象。主要有两个不足:一个是效率问题,另一个是碎片空间太多。
初识 Java 垃圾回收

  • 复制算法

复制算法把内存按照容量划分为两个大小相等的两块,每次只是用其中一块。当这块内存快用完了,将还存活的对象复制到另外一块上面,然后把已经使用过的那块内存空间,全部清理掉。优点:实现简单,运行高效。缺点:浪费了一半的内存空间。
初识 Java 垃圾回收

  • 标记-整理算法

这个算法也是先标记,然后把存活的对象朝一个方向移动,直接清理掉边界之外的所有空间。
初识 Java 垃圾回收

  • 分代收集算法

这种算法根据对象存活的周期的不同讲内存划分几个块,一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用最合适的收集算法。如图所示,水平有限,就不一一介绍了,感兴趣的可以自行搜索。
初识 Java 垃圾回收
垃圾回收有很多内容,这篇文章只是进行简单的介绍。


欢迎大家关注我的微信公众号:卡戎
初识 Java 垃圾回收