1、Java运行时数据区
在JDK8以前,Java运行时数据区域具体分为以下五块:
- 程序计数器(程序寄存器/PC寄存器Program Count Register):每个新开的线程都会有自己的PC。
- 栈(Java栈/堆栈Stack):用来存储对像的引用,基本类型的数据。优点:存取速度快,仅次于寄存器,栈数据可以共享。缺点:存在栈中的数据大小与生存期必须是确定的。
- 本地方法栈(Native Stack):
- 方法区(Method Area):JVM会将二进制class文件的类型信息(类信息、常量,静态变量)放到方法区中,所有线程共享。此区域会开辟一块特殊的空间做”常量池“
- 堆(Heap):用来存储对像实例。也叫GC堆,垃圾回收器主要是对此进行回收。堆是运行时动态分配内存。优点:灵活,因为动态分配内存。缺点:存取速度比栈慢
JDK8后(图片来源于网络):
2、JVM内存模型
Java内存模型(图片来源于网络):
主内存与工作内存的交互流程:
lock(锁定)—>unlock(解锁)---->read(读取主内存变量)---->load(将从主内存读取的变量载入至工作内存)—>use(在工作内存中使用此变量)---->assign(在工作内存中进行赋值操作)---->store(存储,把工作内存的变量传递给主内存)---->write(将从工作内存中得到的变量写入主内存变量中)
volatile关键字,就是用于确保这些变量在主内存到工作内存或工作内存到主内存的流程是完整的,确保数据的同步性。