0%

Java内存模型

Java内存模型即Java Memory Model,简称JMM。JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。

Java的内存模型,采用的是共享内存模型,线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。

Java内存区域的划分

Java内存区域主要是指运行时数据区,包括程序计数器、虚拟机栈、堆、方法区、运行时常量池和本地方法栈

程序计数器

程序计数器又被称之为PC寄存器。
每个虚拟机线程都有自己的程序计数器,用于保存虚拟机正在执行字节码指令的地址。

虚拟机栈

每个Java虚拟机线程都有自己的私有的Java虚拟机栈,和线程同时创建,用于存储栈帧。

堆是可供各个线程共享的运行时的内存区域,也是供所有类实例和数组对象分配内存的区域。
Java堆是在虚拟机启动的时候就被创建,它存储了被垃圾收集器所管理的各种对象。

方法区

方法区是可供各个线程共享的运行时的内存区域。是用于存储每一个类的结构信息。

运行时常量池

运行时常量池是每一个类或接口的常量池的运行时表现形式,包含了若干种不同的常量:从编译器可知的数值字面量到必须运行期解析后才能获得的方法或字段引用。

每一个运行时常量池都分配在Java虚拟机的方法之中,在类和接口被加载到虚拟机之后,对应的常量池就被创建出来了。

本地方法栈

本地方法栈是用于Java虚拟机存储native方法。如果Java虚拟机不支持native方法,可以是没有这个本地方法栈的,如果支持本地方法栈,那么这个栈一般会在线程创建的时候按照线程分配。

Java的内存模型JMM

Java虚拟机规范中定义了Java内存模型的规范,原始的Java内存模型存在一些不足,因此Java内存模型在Java1.5时被重新修订。这个版本的Java内存模型在到现在仍然在使用。
JMM规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。

可以在线程之间共享的内存被称之为堆内存或共享内存。所有实例字段,static字段和数组元素都存储在堆内存中,局部变量,形式方法参数和异常处理参数绝不会再线程间共享,并且不受内存模型的影响。

如果线程A与线程B之间要通信的话,必须要经历下面2个步骤:

1)线程A把本地内存A中更新过的共享变量刷新到主内存中去。

2)线程B到主内存中去读取线程A之前已更新过的共享变量。