JMM和JVM内存区域及硬件内存架构
第一节:java的内存模型,jvm内存区域,硬件的内存架构联系和区别
内容
1.jvm和线程
2.jvm的内存区域及作用
3.JMM(java内存模型)
4.硬件架构和java的内存模型
5.JMM和并发编程的关系
程序:就是一段代码块,去完成某一件任务
进程:就是程序在某些数据上的一次运行
线程:cpu的调度单位,一个进程中可以包含多个线程
一个程序->一个进程->多个线程
问题1:线程是什么时候启动的:
运行期间
问题2:jvm和线程什么关系:
类被调用 jvm系统线程–>调用其他的线程(main)
其实JVM就是一个进程,里面包含多个线程
问题3:jvm是如何启动的:
觉得这篇文章写的挺好的!!!
深入理解JVM(二)——JVM在什么时候启动的
方法区:
方法区是系统分配的一个内存逻辑区域,是JVM在装载类文件时,用于存储类型信息的(类的描述信息)。
方法区存放的信息包括:
类的基本信息:
1.每个类的全限定名
2.每个类的直接超类的全限定名(可约束类型转换)
3.该类是类还是接口
4.该类型的访问修饰符
5.直接超接口的全限定名的有序列表
已装载类的详细信息
1. 运行时常量池:在方法区中,每个类型都对应一个常量池,存放该类型所用到的所有常量,常量池中存储了诸如文字字符串、final变量值、类名和方法名常量。
2. 字段信息:字段信息存放类中声明的每一个字段的信息,包括字段的名、类型、修饰符。
3. 方法信息:类中声明的每一个方法的信息,包括方法名、返回值类型、参数类型、修饰符、异常、方法的字节码。
(在编译的时候,就已经将方法的局部变量、操作数栈大小等确定并存放在字节码中,在装载的时候,随着类一起装入方法区。)
4. 静态变量:类变量,类的所有实例都共享,我们只需知道,在方法区有个静态区,静态区专门存放静态变量和静态块。
5. 到类classloader的引用:到该类的类装载器的引用。
6. 到类class 的引用:虚拟机为每一个被装载的类型创建一个class实例,用来代表这个被装载的类。
PC(程序计数器)
用来记录当前执行的字节码指令的位置。
多线程并发的情况下,线程会进行上下文的切换,我们需要PC来记录我们上一次执行到哪儿了,因此它是线程私有的。
VM Stack
Java方法在运行的内存模型
栈(OOM):栈溢出。
栈深度 栈分配内存的大小。
每一个方法被调用就会产生给你一个栈帧,栈帧里面除了局部变量表还有一个操作数栈;
操作数栈的解释:
堆:
这一块内存是非常非常重要的。
实例对象 GC (信息共享) (OOM)
我们实例化的所有对象都是存放在这个内存中。这个实例化的对象里面会包含一些数据
Native method stack:
如果你去看源码会发现很多地方的代码不是java写的,而是走的native方法去调用本地操作系统里面的一些方法,可能调用的都是c语言写的方法。
比如说:public native int hashCode();
在调用这种native方法的时候,就会有线程对应的本地方法栈,这个其实类似于java虚拟机栈。也是存放各种native方法的局部变量表之类的信息。
java内存的目标:定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节
-
主内存: 共享信息(对应的是堆和方法区)
-
工作内存:(对应的是栈,pc)私有的信息(线程独有的)(工作空间:线程独自操作的一块内存空间),基本的数据类型会直接分配到工作内存,引用的数据类型,引用地址放在工作内存,对象放在主内存中
VM Stack是可以进行设置的,工作空间具体分配是看栈帧的大小,当工作空间的内存>VmStack就hi溢出
-
工作方式:
A : 修改私有数据,把数据写入到内存
B : 线程修改共享数据,先从内存中去拿数据,复制到内存空间中。在工作空间内修改,完成以后, 刷新到内存
为什么要这样设计呢?
是为了保障数据的不可见性,因为每个线程都有自己独立的局部变量,但是因为这种情况加粗样式也就造成了线程的不安全性;
加粗样式
线程A:把共享变量进行读到自己工作空间正在修改
线程B:把共享变量进行读取,那么它读到的就是一个脏数据
1)硬件架构
a)CPU缓存的一致性问题:并发处理的不同步
b)解决方案:
i.总线加锁() 降低CPU的吞吐量
ii.缓存上的一致性协议(MESI)
MESI解释:
当CPU在CACHE中操作数据时,如果该数据是共享变量,数据在CACHE读到寄存器中,进行新修改,并更新内存数据
CaCHE LINE置无效,其他的CPU就从内存中读数据
2)Java线程与硬件处理器
3)Java内存模型与硬件内存架构的关系
并发编程的三个重要特性
原子性:不可分割 x=1
可见性:线程只能操作自己工作空间中的数据
有序性:程序中的顺序不一定就是执行的顺序
编译重排序
指令重排序
提高效率
JMM对三个特征的保证
1)JMM与原子性
A)X=10 写 原子性 如果是私有数据具有原子性,如果是共享数据没原子性(读写)
B)Y=x 没有原子性
a) 把数据X读到工作空间(原子性)
b) 把X的值写到Y(原子性)
C)I++ 没有原子性
a)读i到工作空间
b)+1;
c)刷新结果到内存
D)Z=z+1 没有原子性
a)读z到工作空间
b)+1;
c)刷新结果到内存
多个原子性的操作合并到一起没有原子性
保证方式:
Synchronized
JUC Lock的lock
2)JMM与可见性
Volatile:在JMM模型上实现MESI协议
Synchronized:加锁
JUC JUC Lock的lock
3)JMM与有序性
Volatile:
Synchronized:
Happens-before原则:
1)程序次序原则:最终结果要一致
2)锁定原则 :后一次加锁必须等前一次解锁
3)Volatile原则:霸道原则
4)传递原则:A—B —C A–C
总结:
JVM内存区域和JMM的关系
JMM和硬件的关系
JMM和并发编程三个重要特征(有序性 as-if-seria:结果最终一致 happens-before 不满足这个规则的才可以进行重排序 )
如果有错误,请提示我改正哦!
上一篇: html+css简单网页练习
下一篇: 复习HtmL(超文本标记语言)制作网页