多任务处理为什么在OS中几乎是一项必备的功能?
sadsa
sadsa①、计算机的运算能力强大了,但其运算速度与它的存储和 通信子系统的速度 差距太大了,不匹配,大量的时间都花费在磁盘I/O、网络通信或者数据库访问上。为了避免处理器大部分时间处于"空闲状态",所以我们要让其动起来,避免造成很大的性能浪费。
sadsa②、一个 服务器要对多个客户端提供服务,这是Java语言最擅长的领域之一,我们通过参数:TPS(每秒事务处理数)来衡量服务性能的好坏。
sadsa
为什么内存和处理器之间要加入"高速缓存"?
sadsa
sadsa因为计算机的存储设备与处理器的运算速度有着几个数量级的差距,所以现代计算机系统都不得不加入一层或多层读写速度尽可能接近处理器运算速度的高速缓存来作为内存与处理器之间的缓冲。
sadsa[注]:基于高速缓存的存储交互很好地解决了处理器与内存速度之间的矛盾,但是也为计算机系统带来更高的复杂度,它引入了一个新的问题:缓存一致性(Cache Coherence)
sadsa
什么是“缓存一致性”问题呢?
sadsa
sadsa在多路处理器系统中,每个处理器都有自己的高速缓存,而它们又共享同一主内存。当多个处理器的运算任务都涉及同一块主内存区域时,将可能导致各自的缓存数据不一致,这就是"缓存一致性"问题。如图:

sadsa
什么是乱序执行呢?
sadsa
sadsa为了使处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果是一致的,但并不保证程序中各个语句计算的先后顺序与输入代码中的顺序一致,因此如果存在一个计算任务依赖另外一个计算任务的中间结果,那么其顺序性并不能靠代码的先后顺序来保证。
sadsa[注]:Java虚拟机的即时编译器中也有指令重排序优化。
sadsa
什么是Java内存模型?
sadsa
sadsa用来屏蔽各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。
sadsa
定义Java内存模型要注意什么?
sadsa
sadsa①、这个模型必须定义得足够 严谨,才能让Java的并发内存访问操作不会产生歧义;
sadsa②、必须定义得足够 宽松,使得虚拟机的实现能有足够的自由空间去利用硬件的各种特性(寄存器、高速缓存和指令集中某些特有的指令)来获取更好的执行速度。
sadsa
Java内存模型的目的是什么?
sadsa
sadsaJava内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到内存和从内存中取出变量值这样的底层细节。
sadsa[注]:
sadsa①、此处的变量包括实例变量、静态变量和构建数组对象的元素,但是 不包括局部变量与方法参数。因为后者是线程私有的,不会共享。
sadsa②、为了获得更好的执行效能,Java内存模型并没有限制执行引擎使用处理器的特定寄存器或缓存来和主内存进行交互,也没有限制即时编译器是否要进行调整代码执行顺序这类优化措施
sads
ssadsadsadadasdsadsasdasdasdsasadsadasdadsaJava内存模型

sadsa[注]:这里的主内存、工作内存与Java内存区域中的Java堆、栈、方法区等并不是同一个层次的对内存的划分,这两者基本上是没有任何关系的。
sadsa从功能角度可以这样划分:
sadsadasda①、主内存主要对应于Java堆中的对象实例数据部分。
sadsadasda②、工作内存则对应于虚拟机栈中的部分区域。
sadsa从更基础的层次上:
sadsadasda①、主内存直接对应于物理硬件的内存 。
sadsadasda②、而为了获取更好的运行速度,虚拟机(或者是硬件、操作系统本身的优化措施)可能会让工作内存优先存储于 寄存器和高速缓存 中。
sadsa
内存间的交互操作有几种?
sadsa
sadsa关于主内存与工作内存之间具体的交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存这一类的实现细节,Java内存模型中定义了8种操作(lock、unlock、read、load、assign、use、store、write)来完成。但是,为了使用方便,进行了简化,如今只用了4种:

sadsacaddsasadsadssadasadsa①、read ②、write ③、lock ④、unlock

sadsa[注]:这只是语言描述上的等价化简,Java内存模型的基础设计并未改变(仍需要8种操作) 。
sadsa
对volatile型变量的特殊规则(不具体分析,只是为了保证体系完整性,高并发中已经分析):
sadsa
sadsa关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制;
sadsa
sadsa当一个变量被定义成volatile之后,它将具备两项特性:
sads234a①、对所有线程的可见性
sads2334a【注】:
sads2334saa⒈指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。而普通变量并不能做到这一点,普通变量的值在线程间传递时均需要通过主内存来完成。
sads2334saa⒉各个线程的工作内存中volatile变量也可以存在不一致的情况,但由于每次使用之前都要先刷新,执行引擎看不到不一致的情况,因此可以认为不存在一致性问题。
sads2334saa⒊volatile变量的运算在并发下一样是不安全的,因为Java里面的运算操作符并非原子操作。因为它只是保证读取的是最新的值,但是在它对这个值进行其他操作期间,可能这个值在主内存中已经改变。
sads234a②、禁止指令重排序优化
sads2334a【注】:
sads2334saa⒈有volatile修饰的变量,赋值后多执行了一个“lock addl$0x0,(%esp)”操作,这个操作的作用相当于一个 内存屏障(指重排序时不能把后面的指令重排序到内存屏障之前的位置)
sads2334saa⒉只有一个处理器访问内存时,并不需要内存屏障;但如果有两个或更多处理器访问同一块内存,且其中有一个在观测另一个,就需要内存屏障来保证一致性了。
sadsa
针对long和double型变量的特殊规则:
sadsa
sadsa在Java内存模型中,要求lock、unlock、read、load、assign、use、store、write这八种(现在是4条)操作都具有原子性,但是对于64位的数据类型(lon g和 double),在 模型中特别定义了一条宽松的规定:允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位的操作来进行, 即允许虚拟机实现自行选择是否要保证64位数据类型的load、store、read和write这四个操作的原子性是。
sads2334a【注】:
sads2334saa⒈当有多个线程共享一个并未声明为volatile的long或double类型的变量,并且同时对它们进行读取和修改操作,那么某些线程可能会读取到一个既不是原值,也不是其他线程修改值的代表了“半个变量”的数值。
sads2334saa⒉在目前主流平台下商用的64位Java虚拟机中并不会出现非原子性访问行为。
sadsa
对于原子性、可见性与有序性的一些分析:
sadsa
sadsaJava内存模型是围绕着在并发过程中如何处理原子性、可见性和有序性这三个特征来建立。
sadsa
sadsa①、原子性:由Java内存模型保证了基本数据类型的访问、读写都具备原子性(long、double在32位JVM中例外,但是在64位虚拟机中也可以实现原子性)。
sads2334a【注】:
sads2334a⒈如果应用场景需要一个更大范围的原子性保证,Java内存模型还提供了lock和unlock操作来满足这种需求。
sads2334s⒉提供了更高层次的字节码指令monitorentermonitorexit来隐式地使用这两个操作。-----对应同步块(synchronized)
sadsa
sadsa②、可见性:volatile的特殊规则保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。因此我们可以说volatile保证了多线程操作时变量的可见性,而普通变量则不能保证这一点。
sads2334a【注】:还有两个关键字能实现可见性:
sads2334a⒈synchronized:对一个变量执行unlock操作之前,必须先把此变量同步回主内存中
sads2334s⒉final:被final修饰的字段在构造器中一旦被初始化完成,并且构造器没有把“this”的引用传递出去 (this逃逸分析)(this引用逃逸是一件很危险的事情,其他线程有可能通过这个引用访问到“初始化了一半”的对象),
sadsa
sadsa③、有序性:Java语言提供了volatilesynchronized两个关键字来保证线程之间操作的有序性:
sadsasdsadavolatile关键字:本身就包含了禁止指令重排序的语义
sadsasdsadasynchronized:则是由“一个变量在同一个时刻只允许一条线程对其进行lock操作”这条规则获得的,这个规则决定了持有同一个锁的两个同步块能串行地进入。
sadsa
先行发生原则:
sadsa
sadsa这些是“天然的”先行发生关系,这些先行发生关系无须任何同步器协助就已经存在,可以在编码中直接使用。
sadsa
sadsa①、程序次序规则:在一个线程内,按照控制流顺序(不是代码顺序) ,书写在前面的操作先行发生于书写在后面的操作。
sadsa②、管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。
sadsa
sadsa③、volatile变量规则: 对一个volatile变量的写操作先行发生于后面对这个变量的读操作
sadsa
sadsa④、线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作。
sadsa
sadsa⑤、线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测
sadsa
sadsa⑥、线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生。
sadsa
sadsa⑦、对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
sadsa
sadsa⑧、如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。

JVM之Java内存模型(基于《深入理解Java虚拟机》之第12章Java内存模型与线程)(上)相关推荐

  1. Java毕设项目基于Bootstrap的读书网站设计与实现(java+VUE+Mybatis+Maven+Mysql)

    Java毕设项目基于Bootstrap的读书网站设计与实现(java+VUE+Mybatis+Maven+Mysql) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + ...

  2. 【C++ Primer 第5版 笔记】第12章 动态内存与智能指针

    转载:http://blog.csdn.net/wwh578867817/article/details/41866315 第 12 章 动态内存 与 智能指针 静态内存 用来保存:(1)局部stat ...

  3. 深入理解Java虚拟机——第十二章——Java内存模型与线程

    硬件效率与一致性 处理器需要与内存交互,但处理器运算速度与对内存的I/O操作速度相差几个数量级,因此现代操作系统不得不加入尽可能接近处理器运算速度的高速缓存来作为内存与处理器之前的缓冲.这样处理器就不 ...

  4. 《深入理解java虚拟机》第2章 Java内存区域与内存溢出异常

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来. 2.1 概述 https://blog.csdn.net/q5706 ...

  5. java投标_基于jsp的招投标系统-JavaEE实现招投标系统 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的招投标系统, 该项目可用各类java课程设计大作业中, 招投标系统的系统架构分为前后台两部分, 最终实现在线上进行 ...

  6. java 理财网站_基于jsp的投资理财网站-JavaEE实现投资理财网站 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的投资理财网站, 该项目可用各类java课程设计大作业中, 投资理财网站的系统架构分为前后台两部分, 最终实现在线上 ...

  7. 售票java代码_基于jsp的铁路售票-JavaEE实现铁路售票 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的铁路售票, 该项目可用各类java课程设计大作业中, 铁路售票的系统架构分为前后台两部分, 最终实现在线上进行铁路 ...

  8. 在线书店java项目_基于jsp的网上书店-JavaEE实现网上书店 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的网上书店, 该项目可用各类java课程设计大作业中, 网上书店的系统架构分为前后台两部分, 最终实现在线上进行网上 ...

  9. 死磕Java多线程(五)---理解CPU高速缓存的工作原理 《JAVA性能优化权威指南》 提到过CPU高速缓存未命中率影响线程切换频率

    https://blog.csdn.net/weixin_44046437/article/details/99101180

最新文章

  1. 对Tensor进行变换 class torchvision.transforms.Normalize(mean, std) 给定均值:(R,G,B) 方差:(R,G,B),将会把Tensor正则化
  2. 金陵科技学院c语言测试,金陵科技学院C语言实验册.doc
  3. mac idea用自带的maven还是_苹果电脑自带截图工具怎么用?mac自带截屏工具使用技巧分享
  4. 20155226 2016-2017-2 《Java程序设计》第一周学习总结
  5. 《数据库原理与应用》(第三版) 第 3 章 关系数据库 习题参考答案
  6. ReentrantReadWriteLock源码解析
  7. mysql数据转储方法_Mysql数据库各种导出导入数据方式的区别(我的理解错误还望指正)...
  8. 大数据 java 代码示例_功能Java示例 第7部分–将失败也视为数据
  9. pytroch model??(查看官方模型写法)
  10. 等额本金-c语言俩个整数除法
  11. JDBC 连接 SQL2005 解决办法
  12. 转:深网 | 中国手机往事:因为雷军、罗永浩们,中国才告别山寨机
  13. oracle表增量同步到hive分区表
  14. access open 知乎_必备技能!国际汇款SCI Open Access费用
  15. 【调剂】河北农业大学2020年硕士研究生招生调剂工作办法
  16. 如何设置迪文T5L串口屏的防盗版功能?
  17. #遗憾#重重的挫败感再次袭来!!!
  18. 4-2 多项式求值   (15分) 本题要求实现一个函数,计算阶数为n,系数为a[0] ... a[n]的多项式 f(x)=∑i=0n(a[i]×xi)f(x)=\sum_{i=0}^{n}(a[i]
  19. 计算机程序设计是干嘛的,程序设计究竟是做什么事情的
  20. 图片保存到手机系统相册中的方法

热门文章

  1. ipmi屏幕(SOL)使用及问题总结
  2. dojo 开发资源_使用Dojo掌握面向对象的开发
  3. MOOG伺服阀D661-4652
  4. 高德地图开发(一)详细配置步骤实现显示简单地图
  5. 表白公式计算机,数学公式的超酷表白
  6. 程序计数器没有OOM
  7. go类型转换及与C的类型转换
  8. 思岚科技激光雷达全面升级:RPLIDAR A1仅需900元,A2测距提升至8米
  9. 谷歌CEO皮查伊暗示要裁员;华为研发投入位居首位;Android 13首个安全更新|极客头条
  10. 中国邮政储蓄银行java开发薪资_中国邮政储蓄银行薪资待遇及职业前景