一、先分类
- Java 对象模型,和Java 在虚拟机中的表现形式有关。
- Java 内存模型,和Java 的并发有关。
- JVM 内存模型,和Java 虚拟机的运行时区域有关。
二、Java 对象模型
Java 对象在JVM 中存储也是有一定的结构的。
HotSpot 虚拟机中,设计了一个OOP-Klass Model。OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass 用来描述对象实例的具体类型。对象在内存中包含三块区域:对象头、实例数据和对齐填充。
每一个Java 类在被JVM 加载的时候,JVM 会给这个类创建一个instanceKlass,保存在方法区,用来在JVM层表示该Java 类。
当我们使用new 来创建一个对象时,JVM 会创建一个instanceOopDescs对象,这个对象包含了对象头以及实例数据。
http://www.hollischuang.com/archives/1910
三、JVM 内存模型
虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。
几个需要特别注意的点:
1、以上是Java虚拟机规范,不同的虚拟机实现会各有不同,但是一般会遵守规范。
2、不同版本的方法区所处位置不同,上图中划分的是逻辑区域,并不是绝对意义上的物理区域。因为某些版本的JDK中方法区其实是在堆中实现的。
3、运行时常量池用于存放编译期生成的各种字面量和符号应用。但是,Java语言并不要求常量只有在编译期才能产生。比如在运行期,String.intern也会把新的常量放入池中。
4、除了以上介绍的JVM运行时内存外,还有一块内存区域可供使用,那就是直接内存。Java虚拟机规范并没有定义这块内存区域,所以他并不由JVM管理,是利用本地方法库直接在堆外申请的内存区域。
四、Java (Java Memory Model(JMM))内存模型
Java 内存模型与多线程相关,也叫作共享内存模型。关于JVM的内存结构的图中可以看到,其中Java堆和方法区的区域是多个线程共享的数据区域。多个线程可能可以操作保存在堆或者方法区中的同一个数据。这也就是我们常说的“Java的线程间通过共享内存进行通信”。
JMM是和多线程相关的,他描述了一组规则或规范,这个规范定义了一个线程对共享变量的写入时对另一个线程是可见的。
Java的多线程之间是通过共享内存进行通信的,而由于采用共享内存进行通信,在通信过程中会存在一系列如可见性、原子性、顺序性等问题,而JMM就是围绕着多线程通信以及与其相关的一系列特性而建立的模型。JMM定义了一些语法集,这些语法集映射到Java语言中就是volatile、synchronized等关键字。
JMM的两条规定:
1、线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写;
2、不同的线程之间无法直接访问其他线程工作内存中的变量,线程变量值的传递需要通过主内存来完成。