原创 | 深入理解Java内存模型(上)!

Java内存模型是学习Java虚拟机中必须要会的一个知识点,而且是重点,经常有人把Java内存模型和Java内存结构混为一谈。

以后别乱点鸳鸯篇了,这俩货真的不是一个品种!

今天我们就一起来看看到底Java内存模型是个啥,希望看完今天的文章,以后就不要再学Java内存模型,为啥不学了?因为已经会了啊!

首先,还是希望大家分清楚几个概念:
1.Java内存模型(今天的主角)
2.Java内存结构
3.Jvm内存结构

应该有不少人对这三个概念不是很熟悉,我之前学习Java虚拟机的时候,也是非常疑惑之这三个货,这都是啥啊,长得有点像啊,再加上Java虚拟机本身就比较难啃,所以这块有疑惑也是很正常了!

经过我的多方资料查找以及请教大佬,得出如下结论,记住啦:

Java内存结构就是jvm内存结构,也就是下面这张图所示

原创 | 深入理解Java内存模型(上)!_第1张图片

需要注意的是在不同的jdk版本中内存结构有些许不一样,不过大致相同,后期会专门写一篇文章分析一下各个jdk版本中内存结构的异同。

现在你要清楚的是,我正在给你解释什么是Java内存结构和jvm内存结构,然后我说了,这俩货是一样的东西,直观上你就可以觉得是上面那张图。

因为程序运行是需要内存空间的,啥内存空间啊,我们电脑现在大多数都有固态硬盘了,想必之前大家也都用过机械硬盘的电脑,大家可以明显感觉到,使用固态硬盘,电脑的运行速度是不是变快了,而且很明显。

那这些硬盘是干啥的,是保存数据的啊,比如128G,512G啊,这些都是比较小的了,不过现在对于固态硬盘是不小的了,固态硬盘相比机械硬盘要贵很多,机械硬盘现在买电脑,如果上面有机械硬盘的话,最低也是1T的了,他们都是保存数据的,不过固态的更快,但是容量越大,保存的数据越多,先记住这个。

我们平常使用电脑,也会说内存啥的,我们在说的时候其实自己也不知道自己到底说的是硬盘还是内存条,还是CPU啊,想必不少人从来没有考虑过这个问题。

在计算机中啊,保存信息主要靠存储器,而存储器又分为内部存储器和外部存储器,内部存储器就是内存了,而这个外部存储器主要就是磁盘了,磁盘又分为硬盘和软盘,而我们电脑中的大部分就都是硬盘了,这里也分为固态硬盘和传统机械硬盘。

不管怎么说吧,磁盘也好内存也罢,就是用来存放数据的。接下来看一个比较重要的图:

原创 | 深入理解Java内存模型(上)!_第2张图片

有人可能不明白,不是在说java内存结构吗,怎么说起这些了,讲这个是为了让你更好的理解java的内存结构,尤其那张图。

以上这个图中有硬盘,也就是我们的外存储器,还有内存其实就是内存储器,还有CPU,就是核心的东西了,比如一个程序,首先是存放在硬盘中的,只有这个程序被加载进内存中之后才能运行,这个时候其实关于这个程序的数据和一些指令都被存放在了内存中,CPU就会去内存中去读取这些数据和指令,然后执行相应操作,这其实就是简单的解释了一个程序是怎么在计算机中运行的。

对于CPU来说,内存其实就是个存放数据和指令的地方,CPU会去读取内存中的数据,从而执行程序,既然内存中是存放数据和指令的,那么内存肯定是有大小的,这个内存其实就是我们说的内存条,电脑的运行内存,比如我的电脑就是16G运行内存,这里的内存通常就是这个。

既然内存有大小,存放数据和指令肯定是要占内存空间的,那么重点来了,比如我们使用javac可以将一个Java源文件翻译成Java字节码指令,然后使用java命令去执行这个字节码文件,当我们输入java然后回车的时候其实就是创建了一个Java虚拟机的进程实例,接着就会将这个字节码文件加载进Java虚拟机中(此进程),既然产生了一个进程实例,那么操作系统就会为其分配地址空间,说白了也就是这个java虚拟机的进程实例有个对应的地址空间,也叫作内存空间,而这个内存空间是有一定的结构的,就是具体的划分为几个模块,也就是这个样子:

原创 | 深入理解Java内存模型(上)!_第3张图片
不同的地方存储的数据是不同的,现在到了这里你起码知道java内存结构,也即jvm内存结构是个啥了,可能有人不明白,为啥花那么大力气去说java内存结构,那是因为在学习java内存模型的时候很多人会把它与java内存结构搞混,所以学习java内存模型的第一步,就要先弄清楚java内存结构是个啥。

ps:关于java内存结构中的各个部分的介绍不在本主题讨论范围之内

接下来我们就开始正式的介绍java内存模型啦!

首先要着重强调的就是java内存模型和java内存结构千万不要搞混了,以上可是花了大篇幅去解释java内存结构的,当我们说起java内存结构,你首先要想到的就是这个图:

原创 | 深入理解Java内存模型(上)!_第4张图片

但是,当我们讨论java内存模型的时候,你首先要想到的应该是这张图:

原创 | 深入理解Java内存模型(上)!_第5张图片
你看吧,两者的差别还是很大的,这里提醒下,以上两张图最好牢记,给张纸,拿个笔就能画出来。

那到底啥是Java内存模型呢?在回答这个问题之前我还想请你好好看看上面的Java内存模型抽象图,不知道你是否看出来Java内存模型与什么有关嘛?

不会吧,这都看不出来,那不是一个线程A和一个线程B嘛?这是啥,不就是多线程嘛,所以记住一点:

Java内存模型是与多线程相关的。

好了,可以说啥是Java内存模型了:

Java内存模型简称JMM,它定义了一个线程对另一个线程是可见的,另外就是共享变量的概念,因为Java内存模型又叫做共享内存模型,也就是多个线程会同时访问一个变量,这个变量又叫做共享变量,共享变量是存放在主内存中的,而且每一个线程都有自己的本地私有内存,如果有多个线程同时去访问一个变量的时候,可能出现的情况就是一个线程的本地内存中的数据没有及时刷新到主内存中,从而出现线程的安全问题。在Java当中,共享变量是存放在堆内存中的,而对于局部变量等是不会在线程之间共享的,他们不会有内存可见性问题,当然就不会受到内存模型的影响。

这是啥?是不是有点官方啊?

那么如果我们被别人问到什么是java内存模型的时候我们该怎么回答呢?这个你最好把这个图简单的画一下,最不济也要说下这个java内存模型抽象示意图,然后就像上面提到的你可以这么回答:

Java内存模型是与多线程相关的,也叫做共享内存模型,多个线程可能会出现同时访问一个共享变量的情况,又因为共享变量是存放在主内存中的,而且每个线程都有自己的本地私有内存,那么可能出现的情况就是一个线程的本地内存中的数据没有及时刷新到主内存中,从而出现线程的安全问题。

如果你能画出来这个图,那解释起来就顺畅多了!

接下来我们再来简单的看下这个java内存模型示意图:

从这张图我们可以看出,线程之间的通信是受jmm控制的,我们就这张图来说,线程A和线程B如何才能进行通信,假如线程A先执行,它会拿到共享变量,然后进行操作产生共享变量的副本,紧接着将本地内存中的共享变量副本刷新到主内存中,这时共享变量也就得到的更新,同理线程B再去操作共享变量就达到了线程A和线程B之间的通信了。

基本上到这里你就知道了什么是java内存模型了,那其实关于到具体的应用当中,java内存模型还有很多内容,比如重排序,volatile关键字和锁等,这其实也牵涉到多线程了,因为本身java内存模型就是多线程相关的,所以在学习java多线程这块知识的时候,很多地方都是要借助这个java内存模型的!

在java中,我个人认为jvm,多线程以及并发编程,这三者是紧密相连的!我们以后慢慢来说。

声明:未完待续!

推荐关注我的公众号,获取精品视频教程资料,还能获取我的原创教程的PDF以及最新更新消息:

原创 | 深入理解Java内存模型(上)!_第6张图片

你可能感兴趣的:(原创,Java虚拟机)