jvm内存模型
1.简介
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
2.内存模型
- 堆(Heap) (线程共享区)
- 方法区(Method Area) (线程共享区)
- 程序计数器(Program Counter Register)
- 虚拟机栈(VM Stack)
- 本地方法栈(Native Method Stack)
灰色部分(Java栈,本地方法栈和程序计数器)是线程私有,不存在线程安全问题,橙色部分(方法区和堆)为线程共享区,存在线程不安全问题。
2.1堆(存放对象)
堆(Heap)一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的。堆中保存着所有引用类型的真实信息(即 对象 ),以方便执行器执行。
2.1.1堆的分区(java8)
Java8后的堆物理上只分为新生区和养老区,Metaspace(元空间)不占用堆内存,而是直接使用 物理内存。
2.1.2 堆分区的原因
Java程序中不同对象的生命周期不同,70%~99%对象都是临时对象,这类对象在新生区“朝生夕死”。如果没有分区,GC时搜集垃圾需要对整个堆内存进行扫描;分区后,回收这些“朝生夕死”的对象,只需要在小范围的区域中(新生区)搜集垃圾。所以,分区的唯一理由就是为了优化GC性能。
2.2java栈(放对象的引用)
Java栈也称为虚拟机栈 ,每个线程在创建的时候都会创建一个虚拟机栈,其内部保存一个个 栈帧 (Stack Frame)。每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)。
- Java虚拟机栈是线程私有的,它的生命周期与线程相同(随线程而生,随线程而灭)。
- 栈帧包括局部变量表(8种基本数据类型,对象引用地址)、操作数栈、动态链接、方法返回地址 和一些附加信息。
- 每一个方法被调用直至执行完毕的过程,就对应这一个栈帧在虚拟机栈中从入栈到出栈的过程。
2.3方法区
方法区是供各线程共享的运行时内存区域。它存储了已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。
2.4程序计数器
程序计数器 (Program Counter Register)又叫PC寄存器。每个线程都有一个程序计数器,是线程私有的,是一块较小的内存空间。它是一个指针,指向方法区中的方法字节码,用来存储指向下一条指令的地址,也即将要执行的指令代码,由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。 由于 Java 虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器内核都只会执行一条线程中的指令。CPU需要不停地切换各个线程,有了程序计数器后,当CPU切换回来后,我们就可以知道接着从哪开始继续执行程序。
2.5本地方法栈
虚拟机栈用于管理Java方法的调用,而本地方法栈则是用于管理本地方法的调用
|