带你一文入门JVM运行时内存区域
1. JVM是什么?
JVM:Java Virtual Machine, Java虚拟机。JVM相当于一个计算机,主要工作就是把Java程序生成的字节码文件,解释成具体系统平台上的机器指令。
2. Java的跨平台
Java语言的跨平台性依靠JVM来实现的。
计算机的运算操作的是01指令,也就是机器语言,由程序员编写的java文件使用javac.exe
编译生成class文件,也就是字节码文件,字节码文件上JVM运行,JVM中内部使用java.exe
解释执行生成特定平台的机器码。
特定平台的机器码就是Java语言具有跨平台性的关键,在不同平台,不管是windows,macOS或者linux,生成的字节码都是一样的,这就是Java语言的跨平台性,一次编译,到处运行,而根据特定平台生成机器码这项工作就交给了JVM,JVM根据不同的平台生成对应能够执行的机器码。

3. 运行时内存区域
代码跑起来所需要的一些信息需要存储在某些地方才能运行,就像数据放在内存里才能跑起来是一个道理, 对于JVM来说,这个存储区域就是:JVM运行时内存区域。
JVM运行时内存区域:
线程隔离
(每个线程独有
的资源):栈 / PC寄存器线程共享
(多个线程共用
的资源):方法区 / 堆 / 运行时常量池
线程共享的内存区域需要考虑线程安全问题,因为是多个线程共用,如果多个线程并发使用,可能会出现一些安全问题,因此需要考虑线程安全问题;而线程隔离的内存区域无需考虑线程安全问题。

3.1 PC Register(程序计数器)
PC Register(程序计数器/PC寄存器)
- 线程私有;
- JVM线程执行Java方法时,PC Register存放当前运行JVM指令的地址;JVM线程执行Native方法时,PC Register存放undefined。
PC:存储字节码指令,提供给执行引擎取指执行。
3.2 Stack(栈)
-
线程私有;
-
栈
分为两类:-
Java Virtual Machine Stacks(虚拟机栈)
- JVM栈为虚拟机执行Java方法服务;
- JVM栈存放frame(栈帧),JVM栈的操作单位为栈帧;
- 调用方法时创建栈帧,方法调用结束时销毁栈帧;
- 每个栈帧包含:局部变量,操作数栈 以及 指向当前方法所在类运行时常量池的引用;局部变量数组和操作数栈的大小在编译器确定;
- 任何时候只有正在执行的方法的栈帧会处于活跃状态。
-
Native Method Stacks(本地方法栈)
Native方法栈
:为虚拟机使用到的Native方法服务;Native方法
:用除Java语言外的其他语言编写的方法。
-
-
Java虚拟机规范中,栈规定的的两种异常情况:
StackOverflowError
异常:线程请求的栈深度大于虚拟机所允许的深度;OutOfMemoryError
异常:栈动态扩展时无法申请到足够的内存。
栈:为虚拟机执行方法服务。
3.3 Heap(堆)
- 存放对象,实例变量和数组;
- JVM启动时创建,由所有的JVM线程共享;
- 堆内存放的对象不会显性释放,如果存在堆内的对象没有引用,那么分配给对象的内存会被垃圾回收器(Garbage Collector)回收;
- 堆可以分为:新生代和老年代。
堆:存放对象实例,也是垃圾回收(GC)的主要区域。
3.4 Method Area(方法区)
-
存放JVM加载类和接口的元数据,存放每个类的结构,如:运行时常量池,字段和方法数据,以及方法和构造器的代码;
-
方法区的实现:JDK 8 之前所有的信息存储在方法区的具体实现(永久代中);JDK 8 之后,信息被分成两部分,类的元信息等存储在方法区的具体实现(元空间中),常量池及静态变量存储在堆中。
方法区:储存的是已经被JVM加载的类信息、常量、静态变量。
3.5 Run-time Constant Pool(运行时常量池)
- 方法区的一部分;
- 存放编译期生成的各种 "字面量" 和运行期的 "符号引用"。
一图读懂JVM内存区域
参考资料
转载自:https://juejin.cn/post/7351708519177568290