Java运行时内存区域与硬件内存的关系1

什么是 jmm?在上一篇文章中,我们了解了计算机由于各个硬件的读取速度之间的巨大差距,和充分利用cpu的性能的手段方法,及其所带来的一系列问题:
为了充分压榨cpu的性能, cpu 会对指令乱序执行或者语言的编译器会指令重排 ,让cpu一直工作不停歇,但同时会导致有序性问题。为了平衡cpu的寄存器和内存的速度差异,计算机的cpu 增加了高速缓存,但同时导致了 可见性问题为了平衡cpu 与 i/o 设备的速度差异,操作系统增加了进程、线程概念,以分时复用 cpu,但同时导致了原子性问题。java 是最早尝试提供内存模型的编程语言。由于java 语言是跨平台的,另外各个操作系统总存在一些差异,java在物理机器的基础上抽象出一个内存模型(jmm)
jmm 可以看作是 java 定义的并发编程相关的一组规范,除了抽象了线程和主内存之间的关系之外,其还规定了从 java 源代码到 cpu 可执行指令的这个转化过程要遵守哪些和并发相关的原则和规范,这样就可以屏蔽各个操作系统的差异,简化多线程编程。
java 运行时内存区域与硬件内存的关系java 内存区域和java内存模型有何区别?这是一个非常容易让人混淆的问题,java 内存区域和内存模型完全是不一样的东西,
java 内存区域, 也叫内存区域、jvm内存模型,和 java 虚拟机(jvm)的运行时区域相关,是指 jvm运行时将数据分区域存储,强调对内存空间的划分。java内存模型,也叫内存模型(jmm),是java 定义的并发编程相关的一组规范,除了抽象了线程和主内存之间的关系之外,其还规定了从 java 源代码到 cpu 可执行指令的这个转化过程要遵守哪些和并发相关的原则和规范,屏蔽各个操作系统的差异。通俗点说: jmm规范了程序中变量的访问规则,保证了操作的原子性、可见性、有序性, 我们下文慢慢道来。我们知道jvm 运行时内存区域是分区域的,分为栈、堆等,其实这些都是 jvm 定义的逻辑概念。但在传统的硬件内存架构中是没有栈和堆这种概念。
其中:
图中栈可以细分为:虚拟机栈(jvm stacks)和 本地方法栈(native method stack)虚拟机栈(jvm stacks): 线程私有,它的生命周期和线程相同 ,描述的是java方法执行的内存模型,每个方法在执行的同时都会创建一个线帧(stack frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每个方法从调用直至执行完成的过程,都对应着一个线帧在虚拟机栈中入栈到出栈的过程本地方法栈(native method stack): 线程私有 ,本地方法栈与虚拟机栈的作用是一样的,只不过虚拟机栈是服务java方法的,而本地方法栈是为虚拟机调用native方法服务的。在java虚拟机规范中对于本地方法栈没有特殊的要求,虚拟机可以自由的实现它,因此 在sun hotspot虚拟机直接把本地方法栈和虚拟机栈合二为一了 。线程开始调用本地方法时,会进入 不再受 jvm 约束的世界。本地方法可以通过 jni(java native interface)来访问虚拟机运行时的数据区,甚至可以调用寄存器,具有和 jvm 相同的能力和权限。jni 类本地方法最著名的应该是 system.currenttimemillis()堆(heap)虚拟机堆是java虚拟机中内存最大的一块,是被所有线程共享的,在虚拟机启动时候创建,java堆唯一的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,随着jit编译器的发展和逃逸分析技术的逐渐成熟,栈上分配、标量替换优化的技术将会导致一些微妙的变化,所有的对象都分配在堆上渐渐变得不那么“绝对”了。
java中栈和堆既存在于计算机的高速缓存中,又存在于主存中,所以两者并没有很直接的关系。
java 线程与主内存的关系java 内存模型(jmm) 抽象了线程和主内存之间的关系,就比如说线程之间的共享变量必须存储在主内存中。在 jdk1.2 之前,java 的内存模型实现总是从 主存 (即共享内存)读取变量,是不需要进行特别的注意的。而在当前的 java 内存模型下,线程可以把变量保存 本地内存 (比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。
什么是主内存?什么是本地内存?主内存 :所有线程创建的实例对象都存放在主内存中,不管该实例对象是成员变量还是方法中的本地变量(也称局部变量)本地内存 :每个线程都有一个私有的本地内存来存储共享变量的副本,并且,每个线程只能访问自己的本地内存,无法访问其他线程的本地内存。本地内存是 jmm 抽象出来的一个概念,存储了主内存中的共享变量副本。java 内存模型其实是一种规范,定义了很多东西:
所有的变量都存储在主内存(main memory)中。每个线程都有一个私有的本地内存 (local memory),本地内存中存储了该线程以读/写共享变量的拷贝副本。线程对变量的所有操作都必须在本地内存中进行,而不能直接读写主内存。不同的线程之间无法直接访问对方本地内存中的变量。这里所讲的主内存、工作内存与 java 内存区域中的 java 堆、栈、方法区等并不是同一个层次的内存划分,这两者基本上是没有关系的,如果两者一定要勉强对应起来,那从变量、主内存、工作内存的定义来看,主内存主要对应于java堆中的对象实例数据部分,而工作内存则对应于虚拟机栈中的部分区域。

瓦斯继电器的作用、基本构造、原理及巡视内容
诺基亚Nokia 3310成功复活,只支持2G网络,还是比iPhone 8受欢迎!
电子线束是什么_电子线束的重要性
CS5080(5V USB输入、双节锂电池串联应用、升压充电管理IC)
国辰机器人:打造地下管廊巡检机器人,为地下管廊“健康扫描”
Java运行时内存区域与硬件内存的关系1
高通V2X开发平台构成
韩国5G套餐价格和服务范围虽饱受诟病,但在全球5G国家中排名第二
企业物联网项目成功指南
四节干电池串联电流是多少安
亚利桑那州Weninger法案在法律上承认了区块链的签名和智能合约技术
换流变压器的特点
新能源电动汽车非车载充电机和车载充电机OBC的区别
精细之至,方显英雄本色——保证源表测量精度的小秘籍
你真的了解银河麒麟操作系统吗
中国移动持续推进OpenUPF,打造5G行业开放UPF繁荣生态
ROG新一代腾讯ROG游戏手机官宣
TECH:基于FPGA的高速以太网适配器卡必备的PCIe Gen3技术
修复破碎机支撑板衬板面间隙很简单,看完这个案例分分钟学会
全球首个橡胶工业互联网平台发布,将助力企业数字化转型升级