V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fatyoung
V2EX  ›  程序员

Java 内存模型中的工作内存跟主内存的物理概念是什么

  •  
  •   fatyoung · 2021-05-13 15:07:10 +08:00 · 2879 次点击
    这是一个创建于 1288 天前的主题,其中的信息可能已经有所发展或是发生改变。
    本地内存=cpu 高速缓存?
    主内存=内存?
    不知道这样理解对不对,看到网上有人说本地内存=cpu 寄存器里的内容,但是我细细一想,如果指的是 cpu 寄存器,那假设有个 cpu 是单核的,只有一个核心,也就是说只有一个寄存器,那本地内存跟主内存之间的可见性问题不就不存在了?因为内存就一份,本地内存也就一份了(一个寄存器)。
    求解答。
    25 条回复    2021-05-14 20:24:28 +08:00
    BBCCBB
        1
    BBCCBB  
       2021-05-13 15:15:51 +08:00
    cpu 的每个核都有自己的工作内存.. 什么 l1,l2,l3, 寄存器.. 目的就是优化访问主内存的耗时.

    单个核的话我理解也是可以降低访问主存的耗时的.

    楼主可以去看看访问主存, l1, l2, l3, 寄存器各需要多少时间..
    Mithril
        2
    Mithril  
       2021-05-13 15:24:19 +08:00
    CPU 里面的叫 Cache 和 Register,内存上的叫 Memory 。
    CPU 在计算时没法直接访问 Memory,会先从 Memory 搬到 Cache 里面然后再从 Cache 里读。
    概念这种不太清楚的话可以看看英文的。
    cqsc
        3
    cqsc  
       2021-05-13 15:41:25 +08:00
    Java 内存模型是对硬件内存、缓存的一层抽象 主要屏蔽 OS 和平台的差异化 可以让你在写 Java 代码的时候不需要过度关注访问内存时的细节
    raaaaaar
        4
    raaaaaar  
       2021-05-13 16:05:55 +08:00 via Android
    了解下存储器的分层体系结构吧,再了解下地址空间,虚拟存储器的概念。
    Jooooooooo
        5
    Jooooooooo  
       2021-05-13 16:10:20 +08:00
    找本操作系统的书看看

    感觉是现代计算机基本的架构没搞明白
    seers
        6
    seers  
       2021-05-13 16:13:38 +08:00 via iPhone
    读一下深入理解计算机原理,基础要打牢啊
    fatyoung
        7
    fatyoung  
    OP
       2021-05-13 16:35:17 +08:00
    @Mithril 所以 java 内存模型里的工作内存就是 CPU 里的 Cache,是这个意思吗?
    fatyoung
        8
    fatyoung  
    OP
       2021-05-13 16:36:34 +08:00
    谢谢楼上所有的回复。。我确实对操作系统的一些概念很模糊
    Mithril
        9
    Mithril  
       2021-05-13 17:41:28 +08:00
    @fatyoung 不是,完全不是一样的概念。
    我说的那个是硬件本身的东西,物理上存在的。
    Java 的 JVM 本身是个抽象的概念,它只是个虚拟机,不是物理上的机器,是运行在操作系统上的。
    总的来说就是 CPU+Memory -> OS -> JVM 这样的关系。
    在两层抽象以后,Java 内存模型里面的这些东西并没有能完全对应的物理概念。它只是在 JVM 这个抽象层次上对物理概念的一个模拟而已。
    fatyoung
        10
    fatyoung  
    OP
       2021-05-13 18:03:21 +08:00
    @Mithril 很感谢老哥的细心解答。我之前是觉得 java 内存模型跟 CPU 是可以联系起来的:JVM 是操作系统里的一个用户态,一个进程,要操作硬件只能通过操作系统内核的一些指令去执行,内核的这些指令就可以直接或间接地给 CPU 发送硬件级别的指令了。这样 JVM 就跟 CPU 联系起来了,所以我就很想知道 java 内存模型里的概念,是不是在 CPU 是能找到对应的物理实现的。
    sagaxu
        11
    sagaxu  
       2021-05-13 19:34:07 +08:00 via Android
    Java 内存模型是建立在抽象虚拟机上的,所有的描述都是针对这个实际并不存在的机器模型。但是具体 JVM 实现,还是要落地的,在不同的 arch 下映射到不同的硬件。

    这个有点类似 OSI 7 层参考模型,对应到实际网络模型时只有 4 层了。
    ljzxloaf
        12
    ljzxloaf  
       2021-05-13 19:53:48 +08:00   ❤️ 1
    主内存和工作内存这概念就是误人子弟,我找了半天发现只有一个出处,就是周志明的那本 jvm 书。搜索“jmm work memory”或者“jmm main memory”都没搜到有用的结果。有时候这些过时的概念真的让人费解,比如分布式领域的“CAP”理论就是典型的例子。

    了解 CPU 的人都知道,CPU 有个 l1 缓存,l1 缓存是每个核的本地缓存,那么就会出现一个对共享变量访问顺序的问题(或者叫一致性问题)。打个比方,CPU0 先修改了共享变量 X,CPU1 应该什么时候感知到这个修改,如果需要立即感知的话,CPU0 在修改的时候就需要把 CPU1 的本地 X 缓存( l1 )先清理掉,但是这样势必会导致 CPU 整体执行效率的下降,而如果不需要保证这点,那 CPU 效率就会提升很多。有人会觉得这种顺序肯定是要保证的吧,其实不一定的,比如在分布式存储上很多都是保证不了这一点,不还是有很多应用吗?单机和分布式是类似的,而多 CPU 已经是分布式架构了。
    如果真的要强行类比的话,主内存好比是 PC 存储结构中的内存( L2 、L3 缓存也算),工作内存就好比是 L1 缓存(一些寄存器也算)。

    为啥说是强行类比呢?因为有更好的类比方式。JVM 规范之于 java 应用来说就如同 ISA 之于 os 上的应用,不同的 ISA 对于多核环境下对共享内存的访问一致性有不同的规则,有的是完全不管顺序,有的可能会保证全局顺序,更多的是介于二者之间的(详情请看论文 1 section 7 );而 JVM 是跨平台的,不可能跟着 ISA 的规则走,那样的话同样的代码运行在不同的平台结果就会不一样,所以得制定一个统一的规则。目前描述这种偏序关系广泛采用的方式是 happens-before,java 也是采用的这种(好像一开始规定了一些乱七八糟的规范,但是我没找到周志明书上写的那些内容出处,如果有找到出处的同学麻烦 @我一下)。



    CPU 缓存的概念性理解
    http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf
    Intel 乱序执行的规范
    http://www.cs.cmu.edu/~410-f10/doc/Intel_Reordering_318147.pdf
    Java 同步规范
    https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html
    ljzxloaf
        14
    ljzxloaf  
       2021-05-13 19:59:09 +08:00
    @ljzxloaf #12 推荐阅读一下《计算机体系结构:量化研究方法》第五章,虽然翻译比较古老,但是应该也能理解
    namelosw
        15
    namelosw  
       2021-05-13 22:27:39 +08:00
    不太熟 Java,但是我理解 Java 的虚拟机和普通 CPU 形式还不太一样

    JVM 和 .Net 的 CLR 是 stack machine,运行的时候指令靠一个 stack 来回弹就够了

    普通 CPU 的指令集操作的是 register machine,有 N 个寄存器地址

    Lua 的虚拟机倒是 register machine
    Michaelssss
        16
    Michaelssss  
       2021-05-13 22:29:57 +08:00
    你就记得,一个是 CPU 能直接看到,一个是 CPU 查找后能看到
    halo117
        17
    halo117  
       2021-05-14 01:35:50 +08:00
    @ljzxloaf main memory 和 working memory 这两个印象是在 JDK 1.5/1.6 旧文档中有提及,现在文档没再提这个,而周志明的书就是按照当时 JVM 文档翻译过来的,虽然书说明为逻辑概念,但 main memory 就是直观理解的内存,而 working memory 就是指 cpu cache 一类。
    fatyoung
        18
    fatyoung  
    OP
       2021-05-14 09:58:14 +08:00
    @halo117 我就是看了周志明老师的那本书才有此疑惑。像楼上那位老哥说的,这之间隔着两层抽象,应该是无法对应上的。
    fatyoung
        19
    fatyoung  
    OP
       2021-05-14 09:58:56 +08:00
    @ljzxloaf 感谢推书。一定会看,也谢谢老哥的详细解答
    fatyoung
        20
    fatyoung  
    OP
       2021-05-14 10:12:24 +08:00
    @ljzxloaf 《 Java 并发编程实战》书中也有对 work memory 跟 main memory 的介绍
    fatyoung
        21
    fatyoung  
    OP
       2021-05-14 10:24:22 +08:00
    其实我还有个疑惑。。。JVM 中的程序计数器( PC 寄存器)的物理实现是不是就类似于 CPU 中寄存器?
    因为这两者都是用于线程切换时保存当前线程执行的指令位置,主要是为了当前线程重新获得时间片之后的后续执行。如果说得不对大家就当看个笑话哈哈。。
    GrayXu
        22
    GrayXu  
       2021-05-14 10:31:44 +08:00
    @halo117 难怪从来没见过这个概念。。。看到这标题直接懵了我
    ljzxloaf
        23
    ljzxloaf  
       2021-05-14 15:09:37 +08:00
    @fatyoung #21
    对应 eip
    halo117
        24
    halo117  
       2021-05-14 20:22:33 +08:00
    搜索一下就找到原文说法了,docs.oracle.com/javase/specs/jvms/se6/html/Threads.doc.html,就是 cpu cache 无疑
    halo117
        25
    halo117  
       2021-05-14 20:24:28 +08:00
    Every thread has a working memory in which it keeps its own working copy of variables that it must use or assign. As the thread executes a program, it operates on these working copies. The main memory contains the master copy of every variable. There are rules about when a thread is permitted or required to transfer the contents of its working copy of a variable into the master copy or vice versa.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1669 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:50 · PVG 00:50 · LAX 08:50 · JFK 11:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.