谭浩的博客

Simple is beauty.

Java 垃圾回收机制

JVM 架构

其中堆内存和垃圾回收联系紧密,运行时创建的 Java 对象在堆内存中存储,当 Java 对象不在被任何对象引用时(引用不可达)被垃圾回收器回收空间。

堆内存被分为 3 个主要空间:

  • 新生代(Young Generation)
    • Eden space:任何在运行时新创建的对象将存储在该区域
    • S0 Survivor Space:年老的对象从Eden区移动到S0
    • S1 Survivor Space:年老的对象从S0移动到S1
  • 老年代(Old Generation)超过一定年龄的对象移动到老年代
  • 永久代 (Permanent Generation)包含元数据信息(例如类和方法信息)[note: Java 8 移除了永久代,使用 Metaspace 代替]

Java 垃圾回收

为了管理堆内存,同时减轻程序猿管理内存的工作,Java 垃圾回收被用于自动管理运行时内存。

Java 垃圾回收机制不需要用户在代码中进行显示的初始化。System.gc() & Runtime.gc()是请求JVM启动垃圾回收的钩子程序。虽然程序员可以通过方法调用请求垃圾回收,但其实际执行权在JVM手中,它并不保证一定会执行垃圾回收的请求。

老年代时垃圾回收过程中的最后一个阶段。

在回收垃圾对象之前,垃圾回收器会调用对象的 finalize 方法,以使对象拥有释放其拥有资源的机会。垃圾回收机制可以保证在释放内存之前调用 finalize 方法,但没有指定顺序和时间。除此之外,任何在 finalize 过程中发生的未被捕捉的异常都将被忽略,实例的finalize过程也将被取消。

垃圾回收器类型

  • Serial Garbage Collector
  • Parallel Garbage Collector
  • CMS Garbage Collector
  • G1 Garbage Collector

四种垃圾回收器,各有各的优点和缺点,用户可以通过传递相应的参数选择相应的垃圾回收器。

Serial Garbage Collector

其为单线程环境设计,它使用一个线程执行垃圾回收的工作,其在执行垃圾回收过程时停止所有的应用线程,该方式不能适用于服务器模式。其最适合单一的命令行程序。使用+XX:+UseSerialGC JVM 参数使用Serial Garbage Collector。

Paralle Garbage Collector

PGC 又被称为吞吐量GC。它是JVM默认的GC。其使用多线程来进行垃圾回收。类似SGC,其在执行垃圾回收时会停止应用程序线程。

CMS Garbage Collector

CMS 使用多线程扫描堆内存标记实例对象,然后清楚标记对象。其在以下条件下会停止所有的应用程序线程。

  • 在老年代标记对象时
  • 在执行垃圾回收时,堆内存内容发生变化

和PGC相比,CMS使用更多的CPU保证更好的应用程序吞吐量。

G1 Garbage Collector

G1 将堆内存分成许多区域,在区域上并行的进行垃圾回收。G1 在回收空间后会压缩可用堆空间,G1 根据最多垃圾优先的原则堆区域进行选择。

GC 选择选项

Option Descrption
-XX:+UseSerialGC Serial Garbage Collector
-XX:+UseParallelGC Parallel Garbage Collector
-XX:+UseConcMarkSweepGC CMS Garbage Collector
-XX:ParallelCMSThreads= CMS number of threads to use
-XX:+UseG1GC G1 Garbage Collector

GC 优化选项

Option Description
-Xms 初始化堆内存大小
-Xmx 最大堆内存大小
-Xmn 新生代内存大小
-XX:PermSize 初始化永久代内存大小
-XX:MaxPermSize 最大永久代内存大小