JVM 将整个内存划分为了几块,分别如下所示:
- 1)、方法区:存储类信息、常量、静态变量等。=> 所有线程共享
- 2)、虚拟机栈:存储局部变量表、操作数栈等。
- 3)、本地方法栈:不同与虚拟机栈为 Java 方法服务、它是为 Native 方法服务的。
- 4)、堆:内存最大的区域,每一个对象实际分配内存都是在堆上进行分配的,,而在虚拟机栈中分配的只是引用,这些引用会指向堆中真正存储的对象。此外,堆也是垃圾回收器(GC)所主要作用的区域,并且,内存泄漏也都是发生在这个区域。=> 所有线程共享
- 5)、程序计数器:存储当前线程执行目标方法执行到了第几行。
我们常说的JVM内存模式指的是JVM的内存分区;而Java内存模式是一种虚拟机规范。
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。
原始的Java内存模型存在一些不足,因此Java内存模型在Java1.5时被重新修订。这个版本的Java内存模型在Java8中仍然在使用。
Java内存模型(不仅仅是JVM内存分区):调用栈和本地变量存放在线程栈上,对象存放在堆上。
关于主内存与工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步到主内存之间的实现细节,Java内存模型定义了以下八种操作来完成:
- read(读取):作用于主内存变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用
- load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
- use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作。
- assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。
- store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作。
- write(写入):作用于主内存的变量,它把store操作从工作内存中一个变量的值传送到主内存的变量中。
- lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态。
- unlock(解锁):作用于主内存变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。