程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

JVM中哪些是线程共享区,哪些是线程独占区

balukai 2025-07-23 13:05:25 文章精选 3 ℃

在区分线程共享区与线程独占区前,我们先了解一下JVM的内存模型

名词解释

也叫方法栈,线程在执行每个方法时都会创建一个栈帧,用来存储局部变量表、操作栈、动态链接、方法出口等信息。是线程私有的,在调用方法时执行入栈,方法返回时执行出栈

本地方法栈

与栈类似,也是用来保存线程执行方法时的信息,不同的是,执行JAVA方法使用栈,而执行native方法使用本地方法栈(可以认为是通过JNI(Java Native Interface)直接调用本地C/C++库,不受JVM控制)。

方法执行完毕后也会像栈一样把相应的栈帧出栈并释放内存空间,遇到异常时会抛出StackOverFlowError和OutOfMemeryError两种错误

程序计算器

这是一块比较小的内存空间,它用来保存着当前线程所执行的字节码位置,每个线程工作时都有一个独立的计数器,与线程的生命周期相同。由于JVM可以并发执行线程,因此会存在线程之间的切换,而这个时候程序计算器就会记录当前程序执行到的位置,以便在唤醒后能恢复现场,继续执行。程序计数器为执行JAVA方法服务,执行native方法时,程序计数器为空。

是JVM管理的内存中最大的一块,堆被所有线程共享,目的是为了存放对象实例,几乎所有的对象实例都放在这里分配。当堆内存没有可用的空间时,会抛出OOM异常。堆是垃圾收集器管理的主要区域,又称为“GC堆”。现阶段的虚拟机都是采用分代回收算法。在分代回收算法的思想中,一般把堆分为:新生代、老年代、永久代(1.8后没有了);新生代又分为:Eden区、From Survivor区、To Survivor区

方法区

也是各个线程共享的内存区域,在逻辑上也算是堆的一部分,但为了与堆进行区分,通常也叫“非堆”区。用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区比较重要的一部分是运行时常量池(Runtime Constant Pool),那为什么会叫运行时常量池呢?因为程序在运行期间可能会把新的常量放到池中,如String.intern()方法。


总结

堆区和方法区是所有线程共享的,栈、本地方法栈、程序计数器是每个线程独占的

以下简单记为:

线程共享:

堆: 这是放对象的地方

方法区: 一般是类定义的成员变量、常量、静态变量、方法

线程独占:

栈: 程序运行才有的,会把运行时的方法压入栈,里面有局部变量等东西

本地方法栈: 调用操作系统方法

程序计数器: 标记代码走到哪里了

Tags:

最近发表
标签列表