JVM内存模型
根据《Java虚拟机规范》JVM内存模型可以分为以下几个部分:
堆Heap、虚拟机栈VM Stack、方法区Method Area、本地方法栈Native Method Area、程序计数器Program Counter Register
下面用一段代码示例及图解展示
1 | public class Math { |
1 | 命令:javap -c Math.class |
堆(Java Heap/GC堆)
- Eden+Survivor(s0+s1)+Old
- 被所有线程共享的内存区域
- new出来的对象
- 可以使用jvisualvm命令查看
唯一目的就是存放对象实例,Java中”几乎“所有对象实例都在这里分配内存。《Java虚拟机规范》对此部分的描述:”所有 的对象实例以及数组都应当在堆上分配“。但是随着即时编译的技术发展,比如逃逸分析技术的日益强大,栈上分配 标量替换优化手段(会分配到方法栈),所以只能说”几乎“
虚拟机栈(Java Virtual Machine Stack/线程栈)
- 线程私有
- 方法在执行时会创建栈帧Stack Frame;用于存放 局部变量表、操作数栈、动态链接、方法出口
《Java虚拟机规范》对虚拟机栈区域规定了2类异常:如果线程请求的栈深度>虚拟机允许的深度,会抛出StackOverflow Error;如果栈容量可以动态扩展,且扩展到无法继续申请到足够内存,会抛出OOM异常(HotSpot虚拟机栈容量不可以动态扩展)
局部变量表
存放编译时确定的基本数据类型(boolean、byte、char、short、int、 float、long、double) 对象引用(reference 类型,不是对象本身,可能是指向对象起始地址的引用指针等) 和 return address
本地方法栈(Native Method Stacks)
- native方法 c实现 作用与虚拟机栈相似
方法区(Method Area)
- 常量+静态变量+类元信息
程序计数器(Program Counter Register)
相关面试题
- 方法区 和 永久代、元空间有什么区别?
- 方法区是理论(规范),接口
- 永久代、元空间是具体实现,实现类
- 永久代:在jdk7以前 堆区
- 元空间:jdk8开始 直接内存
- 为什么这么设计?
- gc的问题
- 应用的问题
- oom概率会更低
- jvm有几个虚拟机栈?
- 一个线程一个
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 个人学习经验分享!