Java 运行时内存分析

Java 运行时内存总结!

内存管理

Java 的内存管理主要由 Java 虚拟机(JVM)自动处理,开发者无需手动分配和释放内存。Java 的内存模型主要分为以下几个部分:

  • 方法区(Method Area):存储类结构信息、常量池、静态变量等。
  • 堆(Heap):存储对象实例,是垃圾回收的主要区域。
  • 栈(Stack):存储方法的局部变量、操作数栈、方法返回地址等。
  • 程序计数器(Program Counter Register):指示当前线程执行的字节码指令地址。
  • 本地方法栈(Native Method Stack):为本地方法服务。

堆内存结构

堆内存进一步细分为:

  • 新生代(Young Generation):包括 Eden 区和两个 Survivor 区(S0 和 S1)。新创建的对象通常先分配到 Eden 区。
  • 老年代(Old Generation):存放经过多次垃圾回收后依然存活的对象。

垃圾回收(Garbage Collection)

垃圾回收是 JVM 自动管理内存的重要机制,主要任务是识别和回收不再使用的对象,释放其占用的内存。垃圾回收主要包括以下几个步骤:

对象存活判断

  • 引用计数法:每个对象有一个引用计数器,当引用计数器为 0 时,对象被判定为垃圾。但这种方法无法处理循环引用问题。
  • 可达性分析(Reachability Analysis):从 GC Roots 开始,搜索从根节点出发的所有引用路径,可达的对象被判定为存活,反之则为垃圾。GC Roots 通常包括:
    • 虚拟机栈中引用的对象。
    • 方法区中类静态属性引用的对象。
    • 方法区中常量引用的对象。
    • 本地方法栈中 JNI 引用的对象。

垃圾回收算法

  • 标记-清除(Mark-Sweep):标记所有存活的对象,然后清除未标记的对象。缺点是可能会产生内存碎片。
  • 标记-整理(Mark-Compact):在标记-清除的基础上,整理存活对象,移动到一端,避免内存碎片。
  • 复制(Copying):将内存分为两块,每次只使用其中一块,当这一块用完时,将存活对象复制到另一块,然后清理已使用的那一块。
  • 分代收集(Generational Collection):根据对象存活周期的不同,将内存分为新生代和老年代,分别采用不同的垃圾回收算法。

垃圾回收器

JVM 提供了多种垃圾回收器,每种都有其适用场景:

  • Serial 收集器:单线程收集器,适用于单核 CPU 环境。
  • ParNew 收集器:Serial 收集器的多线程版本。
  • Parallel Scavenge 收集器:关注吞吐量,适用于后台计算而不需要太多交互的场景。
  • CMS(Concurrent Mark Sweep)收集器:关注最短回收停顿时间,适用于对响应时间有要求的应用。
  • G1(Garbage First)收集器:面向服务端应用,目标是在延迟可控的情况下获得尽可能高的吞吐量。

垃圾回收触发条件

  • 分配内存时 Eden 区已满:触发 Minor GC(新生代垃圾回收)。
  • 老年代空间不足:触发 Full GC(全量垃圾回收)。
  • 方法区空间不足:触发 Full GC。
  • System.gc() 方法调用:建议 JVM 执行 Full GC,但不保证执行。

Java 的内存管理和垃圾回收机制大大减轻了开发者的负担,但理解其工作原理有助于优化程序性能和调试内存问题。

Example Image


Java 运行时内存分析
http://example.com/2024/03/29/JavaSummary01/
作者
JunCCore
发布于
2024年3月30日
许可协议
BY-JUNCCORE