1.简介

JVM内存结构包含五块区域,分别为线程私有的程序计数器、虚拟机栈、本地方法栈,以及线程共享的堆和方法区。

JVM内存结构_jvm

2.堆
(1).存储
用来存储对象的内存空间,几乎所有的对象都存储在堆内存中。

(2).结构

堆分为新生代、老年代和元空间,新生代又分为eden区和survivor区,survivor区又分为from survivor和to survivor。

JVM内存结构_jvm_02

3.虚拟机栈
(1).存储
当一个方法即将被运行时,Java虚拟机首先会在Java虚拟机栈中为该方法创建一块称为“栈帧”的内存区域,栈帧中包含局部变量表、操作数栈、和方法出口信息等。当方法在运行过程中需要使用局部变量时,就将局部变量的值存入栈帧的局部变量表中。 当这个方法执行完毕后,这个方法所对应的栈帧将会出栈,并释放栈内存空间。

(2).StackOverFlowError
如果Java虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就抛出StackOverFlowError异常。

4.本地方法栈
本地方法栈和Java虚拟机栈实现的功能类似,只不过本地方法栈是本地方法运行的内存模型。本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、和出口信息等。

5.程序计数器
(1).存储
用来存储当前线程正在执行的字节码指令的地址。

(2).作用
在多线程的情况下,程序计数器存储当前线程正在执行的字节码指令的地址,当线程被切换回来时,可以继续执行

6.方法区
(1).存储
用来存储已经被虚拟机加载的类信息、静态变量和常量(字符串常量池和运行时常量池)。

(2).结构
方法区是一个逻辑空间,具体信息是存储在堆内存中的。堆中有一块本地内存元空间,因为可以扩展,所以会存放不确定大小的类信息和运行时常量池,而静态变量和字符串常量池则存储在堆的其它区域。

7.类加载
(1).Java类加载过程
Java源文件.java被编译器编译成二进制文件.class,然后类加载器将.class文件加载进JVM内存。
JVM读取.class文件,转为方法区数据结构并存储到方法区(堆的元空间),最后生成一个代表该类的Class对象并存储到堆内存。

(2).类加载器

JVM内存结构_java_03


Bootstrap ClassLoad(启动类加载器):负责加载%JAVA_HOME%lib下的class文件。

Extension ClassLoad(扩展类加载器):负责加载%JAVA_HOME%lib/ext下的class文件。

Application ClassLoad(应用类加载器):负责加载classpath下的class文件。

(3).双亲委派模型
JVM在加载类时,会首先委派Application ClassLoad的双亲Bootstrap ClassLoad和Extension ClassLoad加载该类,如果Bootstrap ClassLoad没有加载到,则使用Extension ClassLoad加载,如果还没有加载到,则使用Application ClassLoad加载。