JVM内存模型

JVM内存模型

JVM(Java Virtual Machine)内存模型是 Java 程序在运行时,JVM 为其分配的内存结构,它定义了 Java 程序如何在内存中存储数据和如何进行线程之间的通信。JVM 内存模型是为了支持高效的多线程执行和垃圾回收机制。

一、JVM 内存模型的组成部分:

JVM 内存模型可以分为以下几个主要部分:

1.方法区(Method Area):
  • 作用:用于存储类信息、常量、静态变量和即时编译器(JIT)编译后的代码等数据。可以认为是JVM内存的一部分,是所有线程共享的区域。
  • GC:方法区的回收机制也称为"永久代(Permanent Generation)",但在 JDK 8 后,它被移除,改为使用元空间(Metaspace)。元空间存储类的元数据,不再占用堆内存。
2.堆(Heap):
  • 作用:存储 Java 中所有的对象实例和数组,是 Java 内存中最大的一部分,所有线程共享。堆内存是垃圾回收器(GC)的主要工作区域。
  • GC:Java的垃圾回收器负责清理堆中的无用对象,从而避免内存泄漏和减少内存占用。
3.栈(Stack):
  • 作用:每个线程都有一个独立的栈。栈内存存储方法的局部变量、操作数栈、部分方法的返回地址等信息。每次调用方法时,会创建一个栈帧(stack frame),方法执行结束后,该栈帧会被销毁。
  • 局部变量:栈上存储的是方法中的局部变量、对象引用(并不是对象本身)等数据。栈中的内存是线程私有的,不会被其他线程共享。
4.程序计数器(PC寄存器):
  • 作用:程序计数器记录的是线程当前执行的字节码指令的地址。每个线程都有一个独立的程序计数器,线程切换时不会丢失执行的上下文信息。
  • 特殊性:对于本地方法(Native Method),程序计数器的内容会为空,因为它不执行字节码指令。
5.本地方法栈(Native Method Stack):
  • 作用:本地方法栈与栈类似,但它是用于支持本地方法(native methods)的执行。它存储的是调用本地方法(如通过 JNI 调用的 C 代码)的相关信息。
  • 区别:与 Java 栈相比,本地方法栈是用于管理本地代码的执行,不处理 Java 字节码。

二、JVM 内存的分配:

1.线程共享与线程私有:
  • 堆和方法区是所有线程共享的内存区域。
  • 每个线程有自己的栈、程序计数器和本地方法栈。
2.内存分配与回收:
  • 在堆中,内存分配通常是由垃圾回收器管理的。随着对象的创建和销毁,垃圾回收器会自动回收不再被引用的对象。
  • 栈的内存分配和销毁由方法调用和返回控制。每当方法调用时,栈就会分配一个新的栈帧;方法执行完毕后,该栈帧会被销毁。

三、JVM 内存模型的关键特性:

  • 内存模型的并发性:Java 内存模型(JMM)保证了多线程下对共享变量的访问是可见的。JVM 内存模型规定了线程如何通过主内存和工作内存(缓存)共享数据。
  • 内存屏障和同步:JVM 内存模型定义了"happens-before"规则,确保了多个线程访问共享变量时的有序性,避免了并发中的内存可见性问题。

四、垃圾回收与内存管理:

JVM 的垃圾回收机制负责自动回收不再使用的对象,常见的垃圾回收算法包括:

  • 标记-清除算法:标记所有要回收的对象,然后清除它们。
  • 复制算法:将对象分配到不同的区域,然后清理整个区域。
  • 分代收集:根据对象存活的时间将堆分为多个区域,分别采用不同的回收策略。

五、内存区域图示:

java 复制代码
+----------------------------+
|        程序计数器(PC)       |
+----------------------------+
|       本地方法栈(Native)    |
+----------------------------+
|         栈(Stack)          | <--- 每个线程
+----------------------------+
|          堆(Heap)          | <--- 所有线程共享
+----------------------------+
|      方法区(Method Area)   |
+----------------------------+

六、JVM内存模型通俗易懂的例子:

JVM内存模型的工作方式可以类比为一个厨房或公司的工作环境。我们将JVM的不同内存区域比作不同的区域,每个区域有不同的功能和作用。

1. 方法区(Method Area)
  • 类比:厨房的储藏室
    • 方法区用于存放所有类的信息,包括类的结构、常量池、静态变量等。
    • 这里相当于厨房的储藏室,存放的是所有菜谱(类定义)和厨房用具(静态变量、常量)。
2. 堆(Heap)
  • 类比:厨房的锅和食材
    • 堆是存放所有对象的地方,所有的Java对象都存放在堆上。
    • 类似厨房中的锅和食材,员工(线程)在这里工作并储存自己的食材(对象)。堆是所有线程共享的资源。
3. 栈(Stack)
  • 类比:每个员工的工作台
    • 每个线程有自己的栈,栈用于存储方法调用的栈帧(局部变量、方法参数等)。
    • 就像每个员工有自己的工作台,每个人独立地完成自己的任务,不互相干扰。
4. 程序计数器(Program Counter,PC)
  • 类比:员工的任务进度表
    • 程序计数器记录当前线程执行的指令位置(即下一个执行的指令)。
    • 就像每个员工都有自己的任务进度表,记录他们当前在做什么。
5. 本地方法栈(Native Method Stack)
  • 类比:员工在外部执行特殊任务时使用的工具
    • 本地方法栈用于执行本地方法(通常是用C/C++编写的代码)。
    • 类似于员工在外部做任务时需要的特殊工具或设备。
6、内存区域协作
  • 多线程共享资源: 方法区和堆是所有线程共享的,就像厨房中的食材和工具,多个员工(线程)可以同时使用。
  • 每个线程独立工作: 每个线程都有自己的栈和程序计数器,就像每个员工有自己的工作台和任务进度表,互不干扰。
7、垃圾回收(GC)
  • 类比:清理厨房的无用物品
    • 当堆中的对象不再被引用时,JVM会回收这些对象,就像厨房清理掉不再使用的食材或工具。
    • 这个过程称为垃圾回收(GC),目的是释放内存空间,让其可以被其他对象使用。
8、小结

JVM内存模型就像一个组织良好的厨房或公司,每个员工(线程)有自己的工作空间(栈和程序计数器),但他们共享一些资源(方法区和堆)。垃圾回收机制确保了不再使用的对象能够被清理,保持内存的高效利用。

七、JVM调优

八、总结:

总结来说,JVM 内存模型通过合理的内存分配和回收机制,为 Java 程序提供高效的运行环境,并确保多线程并发执行时的内存一致性。

相关推荐
qw9491 小时前
JVM:程序计数器、虚拟机栈、本地方法栈
jvm
Mr.每天进步一小步4 小时前
每天记录一道Java面试题---day39
java·jvm·面试
DreamBoat_Onism6 小时前
JVM 垃圾回收
java·jvm·后端
DreamBoat_Onism7 小时前
JVM 内存调优
java·jvm·后端
异常君7 小时前
深入 JVM:线程池源码剖析与性能调优全攻略
java·jvm·后端
zimoyin8 小时前
整活 kotlin + springboot3 + sqlite 配置一个 SQLiteCache
jvm·sqlite·kotlin
DreamBoat_Onism12 小时前
JVM 概述
java·jvm·后端
你不干有的是帕鲁干1 天前
jvm问题总结
java·jvm
꯭ 瞎꯭扯꯭蛋꯭1 天前
JVM 常用监控工具介绍和使用
jvm
qw9491 天前
JVM:JVM与Java体系结构
java·开发语言·jvm