跳到主要内容

前言

对于Java内存模型,我相信刚学习JVM的小伙伴会直接想到Java内存区域,我也是这么觉得的,例如,堆、本地方法栈,方法区,程序计数器这之类的,但是他们不是一个概念,前面说的这个是Java内存区域,并非Java内存模型,对于Java内存模型又叫(Java Memory Model简称为JMM),所以说各位小伙伴不要像我一样搞混了

Java内存区域

再说Java内存模型之前,我们先来看一下Java内存区域,这个我相信大家已经牢记于心了,也就是下面这个图

image.png

图中红色的区域代表着线程之间共享的区域,而黄色的区域代表线程之间私有的区域

方法区

对于方法区这个区域,他主要存放的是类信息,常量信息,静态变量等

对于堆这个区域,他是Java内存区域的最大的一部分,我们经常通过new来实例化一个对象,我们实例化的对象都是放在这个区域中的,并且我们经常听到的垃圾回收,垃圾回收都是基于堆这个区域的。

本地方法栈

对于本地方法栈这个区域,这个部分我们基本不需要管,我们看到Java中调用的native方法,这些本地方法都是从这个区域中调用的

虚拟器栈

对于虚拟器栈这个区域,这个区域主要存放栈帧,比如一些对象的引用,每一个方法的调用开始到结束就相当于,入栈到出栈的过程

程序计数器

对于程序计数器这个区域,这个区域我们基本上也不需要管,这个区域主要存放着下一条指令的地址

Java内存模型

Java内存模型(Java Memory Model简称为JMM),他是一种抽象的概念,并不真实的存在。由于JVM运行程序的实体是线程,每一个线程创建的时候都会为其创建一个工作内存,用于存储线程私有的数据,而Java内存模型中规定,所有变量都存储再主内存中,主内存是共享区域,所有的线程都能访问到,但是线程对于变量的操作必须再工作内存中进行,首先要将变量从主内存拷贝到自己的工作内存中,然后再进行修改,修改完成之后再将变量写回主内存,不能直接去操作主内存中的变量,同样的,线程间的工作内存也是隔开的,我们不能直接取访问其他线程的工作内存,必须要经过主内存来完成

image.png

指令重排序

我们说一下什么是指令重排序,在JMM中,编译器和处理器会遵循数据依赖性原则,来给指令进行重排序,从而加快程序运行速度,可能又会有小伙伴不明白什么是数据依赖性了

数据依赖性

数据依赖性指的就是对于下面这段代码,b对于a就是有数据依赖性的,如果没有a那么必然报错,在JMM中,会给我们的指令进行重排序,从而达到加快的目的,就好比int c = 5;,这段代码没有任何数据依赖,那么我们就可以进行指令重排序,也就是把int a = 5;int c = 5;,这些代码放在不同处理器上去运行,加快应用程序运行效率

int a = 5;
int b = a;
int c = 5;