网站首页 > 文章精选 正文
在区分线程共享区与线程独占区前,我们先了解一下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()方法。
总结
堆区和方法区是所有线程共享的,栈、本地方法栈、程序计数器是每个线程独占的
以下简单记为:
线程共享:
堆: 这是放对象的地方
方法区: 一般是类定义的成员变量、常量、静态变量、方法
线程独占:
栈: 程序运行才有的,会把运行时的方法压入栈,里面有局部变量等东西
本地方法栈: 调用操作系统方法
程序计数器: 标记代码走到哪里了
猜你喜欢
- 2025-07-23 线上服务 FGC 问题排查,看这篇就够了
- 2025-07-23 JVM运行时内存区域、堆内存分段机制
- 2025-07-23 JVM运行数据区深度解析(jvm运行时区域)
- 2025-07-23 开发者必备!线上内存泄漏排查的 8 个 Linux 实战工具
- 2025-07-23 内存溢出满分排查步骤,看完不用担心拿不到Offer了
- 2025-07-23 关于JVM调优,看这篇就够了(jvm调优实战简书)
- 2025-07-23 那么大个对象的垃圾回收有什么不同
- 2025-07-23 GC分代年龄为什么是15?(对象gc的分代年龄保存在)
- 2025-07-23 JVM参数调优,一文让你搞懂,再也不为应用操心了!
- 2025-07-23 求你了,别再说 Java 对象都是在堆内存上分配空间了
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)
- fmt.println (52)