返回

JVM垃圾回收原理解析

Android

JVM,即Java虚拟机,是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来完成的。Java语言最重要的特性之一是自动垃圾回收机制,也是基于JVM实现的,而且在我们日常开发中经常会遇到内存溢出、栈溢出、OutOfMemoryError等问题,这些问题的根源都和JVM的垃圾回收机制相关。

JVM垃圾回收的基本原理

JVM垃圾回收的基本原理是:当一个对象不再被任何引用变量指向时,该对象就会被视为垃圾对象,JVM会对垃圾对象进行回收,释放其占用的内存空间。

引用计数

引用计数是一种简单的垃圾回收算法,它为每个对象维护一个引用计数器,当一个对象被引用时,其引用计数器加1;当一个引用变量被销毁时,其引用计数器减1。当一个对象的引用计数器为0时,该对象就会被视为垃圾对象,JVM会对垃圾对象进行回收。

根对象

根对象是指在程序执行期间始终存在且可直接访问的对象,包括:

  • 全局变量
  • 方法参数
  • 局部变量
  • 常量池中的对象
  • 正在执行的线程的栈帧中的对象

可达对象

可达对象是指从根对象出发,沿着引用链能够到达的对象。所有可达对象都是存活对象,不会被JVM回收。

标记清理

标记清理算法是JVM中常用的垃圾回收算法之一。标记清理算法的具体步骤如下:

  1. 标记阶段:从根对象出发,深度优先搜索所有可达对象,并将这些对象标记为“存活对象”。
  2. 清理阶段:遍历整个堆内存,回收所有未被标记为“存活对象”的对象。

标记清除

标记清除算法也是JVM中常用的垃圾回收算法之一。标记清除算法的具体步骤如下:

  1. 标记阶段:从根对象出发,深度优先搜索所有可达对象,并将这些对象标记为“存活对象”。
  2. 清除阶段:将所有未被标记为“存活对象”的对象从内存中清除。

复制收集

复制收集算法是一种比较简单的垃圾回收算法,它将堆内存划分为两个区域:Eden区和Survivor区。

  • Eden区:是新建对象的主要存放区域。
  • Survivor区:是Eden区中存活的对象的存放区域。

复制收集算法的具体步骤如下:

  1. 将Eden区和Survivor区划分为大小相等的两块内存空间。
  2. 将Eden区中的所有对象复制到Survivor区中的其中一块内存空间中。
  3. 清除Eden区中的所有对象。
  4. 将Survivor区中存活的对象复制到另外一块内存空间中。
  5. 清除Survivor区中的所有对象。

分代收集

分代收集算法是JVM中常用的垃圾回收算法之一。分代收集算法将堆内存划分为三个区域:年轻代、老年代和永久代。

  • 年轻代:是新建对象的主要存放区域。
  • 老年代:是长期存活对象的存放区域。
  • 永久代:是存储类信息、方法信息、常量信息等的区域。

分代收集算法的具体步骤如下:

  1. 将年轻代划分为Eden区和Survivor区。
  2. 将新建对象放入Eden区。
  3. 当Eden区满了时,将Eden区中的存活对象复制到Survivor区中的其中一块内存空间中。
  4. 清除Eden区中的所有对象。
  5. 当Survivor区满了时,将Survivor区中的存活对象复制到老年代中。
  6. 清除Survivor区中的所有对象。
  7. 当老年代满了时,JVM会触发Full GC,对整个堆内存进行回收。

垃圾回收器的特点和优缺点

JVM中提供了多种垃圾回收器,每种垃圾回收器都有自己的特点和优缺点。

垃圾回收器 特点 优缺点
Serial GC 单线程垃圾回收器 简单高效,但会造成程序暂停
Parallel GC 多线程垃圾回收器 并行回收,提高了垃圾回收的效率,但会增加程序的开销
Concurrent Mark Sweep GC 并发标记清除垃圾回收器 并发回收,不会造成程序暂停,但效率较低
Garbage First GC 垃圾优先垃圾回收器 优先回收那些即将被回收的对象,减少了内存碎片
Shenandoah GC 低暂停时间垃圾回收器 暂停时间短,适用于对延迟要求较高的应用程序

总结

JVM垃圾回收机制是一个复杂且重要的机制,它可以帮助我们管理内存,避免内存溢出等问题。了解JVM垃圾回收的基本原理和优化技巧,可以帮助我们提高程序的性能和稳定性。