图解JVM内存模型和JVM线程模型

大哥大姐们有没有人讲详细点的我想说明下,图解JVM内存模型和JVM线程模型
最新回答
小茉莉

2026-04-08 09:53:49

JVM内存模型

JVM内存模型即运行时数据区,在JVM1.8中,主要由方法区(元数据区)、堆、虚拟机栈、本地方法栈和程序计数器组成,其中堆和方法区是线程共享的,虚拟机栈、本地方法栈、程序计数器是线程隔离的。

  • 方法区(JVM1.8为元数据区)

    作用:存放虚拟机加载的类型信息,域(Field)信息,方法(Method)信息,常量,静态变量,即时编译器编译后的代码缓存。方法区中存在运行时常量池,字面量、符号引用等存放入其中。

    内存溢出:无法申请到内存时,将抛出OutOfMemoryError。

    Hotspot演变:

    Java6及之前:方法区存在永久代,保存有静态变量。

    Java7:进行去永久代工作,虽然还保留着,但静态常量池,如字符串常量池,已经移动到堆中。

    Java8:移除永久代,类型信息、域(Field)信息、方法(Method)信息存放在元数据区;字符串常量池、静态变量存放在堆区。

    较为完整的JVM内存模型图如下:

    单独的JVM内存模型图如下:

  • 虚拟机栈

    作用:保存每一次方法调用的信息。每个Java线程创建时,都会创建对应的虚拟机栈,每一次方法调用,都会往栈中压入一个栈帧。

    栈帧内容:

    局部变量表:保存函数的局部变量。

    操作数栈:保存计算过程中的结果,即临时变量。

    动态链接:指向方法区的运行时常量池。字节码中的方法调用指令以常量池中指向方法的符号引用为参数。

    方法的返回地址。

    栈帧图如下:

  • 本地方法栈:和虚拟机栈功能上类似,管理native方法的一些执行细节,而虚拟机栈管理的是Java方法的执行细节。
  • 程序计数器

    作用:记录线程执行的字节码行号,如果当前线程正在运行native方法则为空,也有称之为PC寄存器。

    重要性:字节码解释器在工作时,通过改变计数器的值来选取下一跳需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基本功能都需要依赖计数器来完成。Java虚拟机通过轮流切换并分配处理器执行时间实现多线程,在任意确定的时间点,一个处理器只会处理一个线程中的指令,为了正确地处理线程切换后的任务恢复,每一个线程都具有自身的程序计数器。

  • 堆

    作用:提供类实例和数组的内存。

    划分:

    新生代:亦可称之年轻代、New Generation,包括Eden区、Survivor区(S0和S1中存在互相移动,一些文章中的from、to是指移动上的逻辑关系,S0和S1是Survivor区的两个子区)。

    老年代:Old Generation。

    堆内存划分图如下:

    对象创建与GC关系:

    新生成的对象在Eden区。

    触发Minor GC后,还“幸存”的对象移动到S0。

    再次触发Minor GC后,S0和Eden中存活的对象被移动到S1中,S0清空。

    每次移动时,自动递增计数器,超过默认值时(印象中是16),移动到老年代,如果Eden中没有足够内存分配,也将直接在老年代中分配内存。

    老年代中依靠Major GC。

  • 小总结图:

JVM线程模型

Java线程的实现方式有三种,分别是使用内核线程实现、使用用户线程实现、使用用户线程加轻量级进程混合实现,具体如下:

  • 内核线程模型

    实现方式:完全依赖操作系统内核提供的内核线程(Kernel-Level Thread ,KLT)来实现多线程,线程的切换调度由系统内核完成。程序一般使用轻量级进程(Light Weight Process, LWP)这种高级接口,用户进程中通过LWP使用系统的内核线程,由于其一对一的关系,又称为一对一模型。

    优点:用户线程与LWP一一对应,LWP是独立的调度单元,某个LWP在用户进程调用过程中发生阻塞,以及在系统调用中发生了阻塞,都不会影响整个进程的执行。

    缺点:LWP依托内核线程,线程操作需要依赖系统调用,代价较高,需要在用户态(User Mode)和内核态(Kernel Mode)中来回切换;每个LWP都需要一个内核线程进行支持,要消耗一定的内核资源,一个系统仅可支持少量有限的LWP。

    内核线程模型图如下:

  • 用户线程模型

    实现方式:JVM平台实现用户线程(User Thread,UT),完全自行实现创建、调度、销毁,线程的调度不再依赖内核,极少占据内核资源,基本限定在用户态内。

    优点:可以突破量的限制,并且减少线程切换时的损耗。

    缺点:难以利用多核CPU的优势,并且一旦产生系统调用发生中断,其他线程也将被中断,这种多对一模型的实用性较低。

    用户线程模型图如下:

  • 混合模型

    实现方式:又称多对多模型,既存在UT,也存在LWP。创建、切换线程(UT)依旧是廉价的,并且可以拥有大量的线程;同时利用LWP作为UT到KLT(内核线程)的桥梁,享受了系统内核的线程调度、CPU映射,免去了自行实现系统调用的部分。

    优点:进行系统调用时,阻塞整个进程的概率低于用户线程模型。

    混合模型图如下: