java内存模型(Java Memory Model,JMM),其实是jvm的一种规范,规定了jvm的内存模型,屏蔽了不同硬件和操作系统之间的访问差异,同时避免了直接访问硬件内存带来的风险。
运行时数据区(Run Data Area)
数据类型 | 简述 |
---|---|
程序计数器(Program Counter Register) | 线程隔离,记录下一条要运行的指令 |
虚拟机栈(Java Stack) | 线程隔离,生命周期与线程相同,用于存储栈帧(于存储局部变量表、操作数栈、动态链接、方法出口 等信息),服务于java方法 |
本地方法栈(Native Method Stack) | 线程隔离,与虚拟机栈功能类似,不同的是服务于JVM使用到的native方法 |
java堆(Heap) | 线程共享,所有的对象实例以及数组均在堆上分配,是GC的主要处理区域 |
方法区(Method Area) | 线程共享,又称为永久区,存放类信息、常量、静态变量,即时编译器编译后的代码等数据,jdk7之后将常量和静态变量迁移到堆中,jdk8之后将类信息和即时编译器编译后的代码等数据从永久代迁移到元空间中 |
程序计数器
描述:程序计数器占据了很小的一部分内存空间,同时也是虚拟机规范中唯一没有OutOfMemoryError的内存区域,线程隔离,记录线程的当前命令执行
使用场景:对于一个处理器(单核)来说,一个时间点只会执行一条线程中的指令,在有多条指令的线程中,程序计数器会在线程切换时,帮助恢复到正确的指令行。所以每个线程都需要有各自的程序计数器,不互相影响
虚拟机栈(Java栈)
描述:栈为线程隔离并与线程生命周期相同,栈为Java方法执行过程中的内存模型
本地方法栈
描述:作用与虚拟机栈类似,区别于虚拟机栈服务于Java方法(字节码),本地方法栈处理的是底层调用的C或C++方法,JDK的安装目录下,部分C编写的文件就是native方法调用的程序代码
Java堆
描述:对于大部分java应用,java堆都是虚拟机管理内存中最大的一块内存区域,存放在堆中的对象均为线程共享,所以在多线程的时候需要注意线程安全和同步机制的问题
方法区
描述:线程共享,在旧版JDK中被称为永久代,从JDK8开始改为使用元空间