java内存模型

java内存模型都不知道,如何内卷老员工

  • Java 内存模型指 Java 虚拟机如何使用计算机的内存。
  • Java 内存模型指定不同线程如何以及何时可以看到其他线程写入共享变量的值,以及如何在必要时同步对共享变量的访问。

内部java内存模型

  • jvm内部适用的java内存模型在堆和线程栈之间分配内存。

  • java虚拟机中每个线程都有自己的线程堆栈,当线程执行代码时,堆栈会发生变化。
  • 线程堆栈还包含每个正在执行的方法(调用堆栈上的所有方法)的所有局部变量。一个线程只能访问它自己的线程堆栈,每个线程也有自己的局部变量版本。
  • 所有原始类型的局部变量 都完全存储在线程堆栈中,因此对其他线程不可见。一个线程可以将原始变量的副本传递给另一个线程,但它不能共享原始局部变量本身。
  • 堆包含了所有线程创建的对象。

  • 堆上的对象可以被所有引用该对象的线程访问。当一个线程可以访问一个对象时,它也可以访问该对象的成员变量。如果两个线程同时调用同一个对象的方法,它们都可以访问对象的成员变量,但每个线程都有自己的局部变量副本。
public class MyRunnable implements Runnable() {public void run() {methodOne();}public void methodOne() {int localVariable1 = 45;MySharedObject localVariable2 =MySharedObject.sharedInstance;//... do more with local variables.methodTwo();}public void methodTwo() {Integer localVariable1 = new Integer(99);//... do more with local variable.}
}
复制代码
public class MySharedObject {//static variable pointing to instance of MySharedObjectpublic static final MySharedObject sharedInstance =new MySharedObject();//member variables pointing to two objects on the heappublic Integer object2 = new Integer(22);public Integer object4 = new Integer(44);public long member1 = 12345;public long member2 = 67890;
}
复制代码
  • 如上代码所示,每个线程执行methodOne()会创建自己的副本,localVariable1和localVariable2在各自的线程中。静态变量只有一个副本,因此两个线程的localVariable2指向堆中的同一个静态变量副本。而localVariable1则存储在各自的栈中。
  • methodTwo()方法中,每个线程都在堆中创造了一个对象,并指向各自的对象。

硬件内存架构

  • 硬件内存架构与java内部内存架构有所不同,如下为硬件内存架构的简化图

  • 计算机通常有多个cpu,每个cpu中都有自己的寄存器,寄存器执行操作的速度比内存快得多。
  • 每个cpu还有自己的cpu缓存,cpu访问缓存的速度同样高于访问主内存的速度,但通常不如访问寄存器速度快。
  • 计算机还有主内存区,所有cpu都可以访问主内存,主内存比cpu内存大得多。
  • 当cpu需要访问主内存时,会将一部分主内存内容读到cpu缓存,甚至一部分读到cpu的寄存器中。当cpu需要将内容写到主内存时,会先将内容写到寄存器,再写到缓存中,最后在适当时间将值刷新到主内存。
  • 当cpu需要在高速缓存中存储其他内容时,存储在高速缓存中的值通常会刷新回主内存。cpu可以将数据写入部分内存并刷新部分内存,不必读写完整缓存。通常,缓存在称为“缓存行”的较小内存块中更新。一条或多条高速缓存线可被读入高速缓存存储器,并且一条或多条高速缓存线可再次刷新回主存储器。

java内存模型与硬件内存模型之间的桥梁

  • java内存模型与硬件内存架构是不同的,硬件内存架构中不区分堆和栈。堆和栈中的数据可能存在于主内存、cpu高速缓存及cpu寄存器中。
  • 当对象和变量可以存储在硬件的不同区域时,可能会面临以下问题:
    • 线程更新、写入共享变量的可见性。
    • 读取、检查和写入共享变量时的竞争条件。

共享对象的可见性

  • 如果两个或多个线程共享对象,没有正确的使用volatile,则一个线程所做的更新对其他线程不可见。
  • 共享对象最初存储在主存中,在cpu上运行的线程将其读取到cpu的寄存器及缓存中。只要尚未将其更新刷新回主内存,则对象的更新版本对其他线程不可见。每个线程都拥有自己的副本,位于自己的cpu缓存中。
  • 要解决这个问题,可以适用volatile关键字。该volatile 关键字可以确保直接从主内存中读取给定变量,并在更新时始终将其写回主内存。

竞争条件

  • 当多个线程更新同一个共享对象或变量,则可能出现竞争条件。
  • 如果线程a和线程b同时读取主内存中为0的共享变量count,两个线程各自执行了+1的操作。如果顺序执行则变量增加了2,如果同时执行最终的结果可能仅仅是+1。
  • 为解决此问题,可以使用同步代码块,确保同一时间只有一个线程操作该变量。同步块还保证所有在同步块内访问的变量都会从主存中读入,并且当线程退出同步块时,所有更新的变量都会再次刷新回主存,无论变量是否声明为 volatile 或不是。

尾记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。

作者:码中悍刀行
链接:https://juejin.cn/post/6995111381150203934
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

内卷老员工之java内存模型相关推荐

  1. 内卷老员工之java内存模型的happens-before原则

    java内存模型的happens-before原则 前言 happens-before原则是指线程本地内存与主内存的同步关系,只有满足happens-before原则的情况下,线程内存发生变化时,才会 ...

  2. 内卷老员工之三级缓存和伪共享

    cpu三级缓存与伪共享 cpu三级缓存 cpu共有L1 cache.L2 cache.L3 cache三级缓存,速度由高到低.其中L1与L2为cpu核心内共享,L3为所有cpu共享. L1.L2.L3 ...

  3. Java内存模型深度剖析

    作者:Hollis,阿里资深攻城狮 来自:Hollis 为什么要有内存模型 在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事 ...

  4. 再有人问你Java内存模型是什么,就把这篇文章发给他

    前几天,发了一篇文章,介绍了一下JVM内存结构.Java内存模型以及Java对象模型之间的区别.有很多小伙伴反馈希望可以深入的讲解下每个知识点.Java内存模型,是这三个知识点当中最晦涩难懂的一个,而 ...

  5. 再有人问你Java内存模型是什么,就把这篇文章发给他。

    前几天,发了一篇文章,介绍了一下JVM内存结构.Java内存模型以及Java对象模型之间的区别.有很多小伙伴反馈希望可以深入的讲解下每个知识点.Java内存模型,是这三个知识点当中最晦涩难懂的一个,而 ...

  6. 史上最清晰的Java内存模型介绍

    这篇文章的标题看起来很霸气,于是我毫不犹豫转了~并且同样起了个霸气侧漏的标题! 本文转载自:再有人问你Java内存模型是什么,就把这篇文章发给他. 网上有很多关于Java内存模型的文章,在<深入 ...

  7. 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则

    前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...

  8. java 内存模型堆和本地方法

    文章目录 一.java内存模型堆 1.堆特点 2.堆异常 3.堆的性能调优参数 二.本地方方法 一.java内存模型堆 1.堆特点 堆是用于存放对象的内存区域.因此,它是垃圾收集器(GC)管理的主要目 ...

  9. JAVA内存模型及垃圾回收自我总结

    本文为原创,根据<深入理解java虚拟机>和自己的一些理解进行整理,单纯和看其他人的博客感觉不如自己一点点的画和记录来的印象深刻. JAVA内存模型: 上图中:局部变量表所需的内存在编译期 ...

最新文章

  1. 深度学习中的反向卷积
  2. mqtt 传文件断开连接的原因_mqtt 发送消息断开链接
  3. 基于尺寸划分的RGB显著物体检测方法
  4. Django:永别了pycrypto库~
  5. npm安装出错Unexpected end of input at 1:2307
  6. webpack之proxyTable配置
  7. 电子设计竞赛(三)-SPWM与PID
  8. Spring Boot 单元测试详解+实战教程
  9. 学生信息管理系统的价值PHP,php技术对学生管理系统实现的价值研究
  10. 某银行软件中心产品开发流程
  11. matlab调用python数值精度改变吗_Matlab如何调用python脚本-matlab调用python数值精度改变吗 - PS下...
  12. BZOJ1143[CTSC2008] 祭祀river
  13. Android 科大讯飞离线语音识别
  14. 高中信息技术python讲义
  15. (CVPR-2020)Strip Pooling:重新思考场景解析的空间池化
  16. WMware安装win10
  17. HCNP学习笔记之OSPF协议原理及配置1-基础知识
  18. oracle列求平均
  19. linux基础——sed
  20. mybatis中的Example_Where_Clause

热门文章

  1. easyui的简单实例
  2. Python turtle绘制——癸卯(兔)年卯兔图
  3. HapMap-人类基因组单倍型图谱
  4. 好心情精神心理科医生:如何与青春期的孩子沟通?
  5. 使用su命令切换到别的用户时报su:无法打开会话:权限被拒绝
  6. 【工具分享】如何识别手机里偷数据的那些软件(适用于安卓平台)
  7. 输入字体之间的间隔突然变大了
  8. CUDA安装和检测【全】(nvcc命令找不到的解决办法)
  9. pdksh-5.2.14-36.el5.i386.rpm
  10. 智慧能源发展方向、应用趋势