JVM内存模型和GC

JVM内存模型和GC
最新回答
巷陌繁花

2022-03-19 04:11:19

JVM内存模型和GC

JVM(Java Virtual Machine)内存模型是Java程序运行时的内存结构,它定义了Java程序在执行过程中如何分配和管理内存。GC(Garbage Collection)则是JVM中用于自动回收不再使用的内存空间的过程。

JVM内存模型

JVM内存模型主要包括以下几个部分:

1. 方法区(线程共享)
  • 定义:也称为“永久代”、“非堆”,用于存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • 特点:是各个线程共享的内存区域。
  • 运行时常量池:作为方法区的一部分,用于存放编译期生成的各种字面和符号引用,这部分内容在类加载后被放入方法区的运行时常量池中。
2. 虚拟机栈(线程私有)
  • 定义:Java虚拟机栈的生命周期与线程相同,描述的是Java方法执行的内存模型。
  • 内容:每个方法在执行时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
  • 存储内容:8大基本类型、对象引用、实例方法。
  • 栈内存:常说的堆内存、栈内存中,栈内存指的就是虚拟机栈。
3. 本地方法栈(线程私有)
  • 定义:与虚拟机栈类似,但本地方法栈是给本地方法(Native Method)使用的。
  • 作用:支持JVM调用非Java代码(如C或C++编写的本地方法)。
4. 堆(线程共享)
  • 定义:是Java虚拟机管理的最大的一块内存,也是GC的主战场,用于存放几乎所有的对象实例和数组数据。
  • 结构:堆分为新生代和老生代。新生代用于存放新建的对象,当对象经过一定GC次数后仍然存活,则会被放入老生代。新生代还细分为一个Eden区和两个Survivor区(S0/S1)。
  • GC过程:在垃圾回收时,Eden区中存活的对象会被放到一个未使用的Survivor区中,同时清除当前的Eden区和正在使用的Survivor区。

5. 程序计数器(线程私有)
  • 定义:用于记录当前线程执行的行号。
  • 特点:是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。
  • 特殊情况:如果当前线程正在执行的是一个Java方法,程序计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是一个Native方法,则程序计数器的值为空。
  • OOM情况:程序计数器内存区域是唯一一个在JVM规范中没有规定任何OOM(Out Of Memory)情况的区域。
GC(垃圾回收)

GC是Java虚拟机提供的一种自动内存管理机制,用于回收不再使用的内存空间。GC的主要目标是确保Java程序在运行时不会因为内存不足而崩溃,同时尽可能减少内存泄漏和内存碎片。

GC的工作原理
  1. 标记阶段:GC会遍历所有的对象引用,标记出哪些对象是当前正在使用的(可达的),哪些对象是不再使用的(不可达的)。
  2. 清除阶段:对于标记为不可达的对象,GC会将其占用的内存空间回收,以便后续使用。
GC的类型
  • 新生代GC:主要发生在新生代的Eden区和Survivor区之间,用于回收不再使用的年轻对象。
  • 老生代GC:主要发生在老生代区域,用于回收长时间存活的对象。
  • 混合GC:同时涉及新生代和老生代的垃圾回收过程。
GC的触发条件
  • 内存不足:当JVM中的堆内存空间不足时,会触发GC以回收不再使用的内存空间。
  • 显式调用:在某些情况下,可以通过调用System.gc()方法显式触发GC,但这种方式并不保证会立即执行GC。
GC的优化策略
  • 分代收集:根据对象的存活时间将内存划分为不同的区域(如新生代和老生代),并分别采用不同的GC策略。
  • 并发收集:在应用程序运行的同时进行垃圾回收,以减少GC对应用程序性能的影响。
  • 增量收集:将垃圾回收过程分解为多个小步骤,逐步完成整个垃圾回收过程。

综上所述,JVM内存模型和GC是Java程序运行时的关键组成部分。通过合理的内存分配和垃圾回收机制,JVM能够确保Java程序的高效、稳定运行。