JAVA 内存模型

简介

内存模型描述了程序中各个变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的底层细节,对象最终是存储在内存里面的,这点没有错,但是编译器、运行库、处理器或者系统缓存可以有特权在变量指定内存位置存储或者取出变量的值。【JMM】(Java Memory Model的缩写)允许编译器和缓存以数据在处理器特定的缓存(或寄存器)和主存之间移动的次序拥有重要的特权,除非程序员使用了volatilesynchronized明确请求了某些可见性的保证。

想要了解 JAVA 的内存模型,就得了解计算机的内存模型,计算机中并不存在 JVM 的概念,但是真实的数据读写操作又是在计算机中运行的。下面我们先来了解一下计算机的相关知识。

冯·诺伊曼体系

在这里插入图片描述
著名的冯·诺伊曼体系中把计算机划分为5个部分,分别是:

  • 输入设备
  • 输出设备
  • 存储器
  • 运算器
  • 控制器

存储器又分为:主存储器和辅存储器,运算器和控制器构成了计算机的CPU,主存储器就是我们所说的内存,辅存储器对应的是硬盘,这里我们只要关系主存储器。CPU与主存储器之间的数据交换模型,就是神秘的计算机内存模型。

计算机内存模型

在这里插入图片描述
CPU和主存储区的数据有一个过程,CPU要对主存储器中的数据进行操作时,首先要获取主存中的数据,会将主存储中数据复制到CPU缓存区中,(一般都会存在多级缓存区),再将CPU缓存中的数据、指令保存到寄存器中,CPU 内核执行寄存器中的指令,而且运算完成之后并不是马上更新到主存储器中,而是再CPU觉得合适的时候更新数据到主存中。

但CPU中计算遵循了一个标准:线程级别结果正确。即当前线程的数据在寄存器,缓冲区,主存中的数据一致。多个线程可能不一致,这就是导致线程安全的原因,也是学习计算机内存的原因。

JAVA内存模型

稍微了解计算机的内存模型之后,我们再来看看Java的内存模型。
在这里插入图片描述
Java内存模型将JVM划分为两个部分:

  • 线程栈(Thread Stack)
  • 堆(Heap)

那么Java中的变量到底保存在哪呢?这是有明确规定的。

哪些保存在栈中
  • 原始类型局部变量
  • 引用类型局部变量的引用
哪些保存在堆中
  • 引用类型局部变量的引用指向的对象
  • 成员变量(原始类型,引用类型)

保存在栈中的变量是线程安全的,保存在堆中的变量是线程共享的,虽然引用类型局部变量的引用保存在栈中,但是其指向的对象保存在堆中,所以也会存在线程不安全。

分别学习了计算机内存模型和Java语言的内存模型之后,但我们还不知道Java内存模型怎么在真实的计算机中运行的呢?

Java内存模型和计算机内存模型的交互

栈中数据可能保存在计算机的位置

  • cpu寄存器
  • cpu缓冲区
  • 主内存

堆中数据可能保存在计算机的位置

  • cpu寄存器
  • cpu缓冲区
  • 主内存

JVM Thread Stack和Heap中的数据可能在Computer内存中出现的位置有CPU 寄存器,CPU缓冲区,主内存。多线程执行时,数据存在可见性,一致性,原子性等问题。

参考:

发布了126 篇原创文章 · 获赞 75 · 访问量 13万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览