内存模型—软件硬件结合讲JVM内存模型

来源:互联网 发布:百合体验知乎 编辑:程序博客网 时间:2024/04/20 09:51

      JVM是一个完整的计算机模型。侧重理解JVM的内存模型规定如何和何时可以看见由其他线程修改后的共享变量的值,以及如何在必要的时候如何同步的访问共享变量。

      JVM内部原理:


       划分为栈和堆(还有其他的,现只关注这两个)。每个运行在Java虚拟机里的线程都拥有自己的线程栈,这个线程栈包含了这个线程调用的方法当前执行点的相关信息。一个线程只能访问自己的线程栈,一个线程栈创建的局部变量对其他线程不可见。即使两个线程执行同样的代码,这两个线程仍然在自己的线程栈中的代码来创建局部变量。

      所有基本类型的局部变量都存放在栈中,故对其他线程不可见,一个线程能向另一个线程传递一个基本类型的拷贝,但始终不能共享基本变量自身。

      堆上包含在Java程序中创建的所有对象,无论是那一个对象创建的,包括基本类型的包装。如果一个对象被创建然后赋值给一个局部变量,或作为成员变量,都是放在堆上的。

      一个局部变量是基本类型,呆在栈上。若是引用类型,则引用在栈上,对象本身在堆上。

      对象:对象的成员变量随着这个对象自身存放在堆上,不论是基本还是引用类型。对象的方法包含的局部变量存放在栈上。

      静态成员变量随着类定义一起放在堆上。

两个线程访问同一个对象,也能访问这个对象的成员变量。如果调用同一个方法,都会访问到对象的成员变量,但是每个线程都拥有这个局部变量的私有拷贝。???(两个线程访问同一个对象的成员变量,得到的是拷贝)

      硬件内存架构:


      现代硬件内存模型与Java内存模型有一些不同。现代计算机通常由两个或者多个CPU。其中一些CPU是多核,从这点可以看出在一个有两个或者多个CPU的现代计算机同时运行多个线程是可能的。意味着Java程序每个CPU上一个线程可能同时(并发)执行。

       每个CPU内都包含一系列的寄存器,是CPU内存基础。每个CPU可能还有一个或者多个CPU缓存层。计算机还有主存。访问速度从大到小:寄存器>缓存>主存。

       当CPU需要读取主存时,会将主存的部分读至CPU的缓存中,甚至可能将缓冲中的部分内容读至寄存器中,然后再寄存器中执行操作。当CPU需要将结果写回到主存中时,它会将内部寄存器的值刷新到缓存中,再在某时刻刷新回主存;当CPU需要在缓存层存放东西时,存放在缓存中的内容通常会被刷新会主存。CPU缓存可以在某一时刻将数据局部写到内存中,和在某一时刻局部刷新它的内存。它不会在某一时刻读写整个缓存。

       桥接JVM与硬件

       硬件架构没有区分栈和堆,对于硬件所有的栈和堆都分布在主存中,部分栈和堆可以出现在CPU缓存和寄存器中。

       当对象和变量被存放在计算机中各个不同的内存区域中时,主要会出现两方面的问题:1.线程对共享变量修改的可见性;2.读、写、检查共享变量时出现race condition。

      1.volatile可以保证直接从主存中读取一个变量,如果变量修改后,总是会被写回主存中去。

      2.使用同步块。一个同步块可以保证在同一时刻仅有一个线程可以进入代码的临界区。同步块还可以保证代码块中所有被访问的变量将会从主存读入,当线程退出同步代码块时,所有被更新的变量都会被刷新回主存中去。
0 0
原创粉丝点击