JVM——内存模型

这篇具有很好参考价值的文章主要介绍了JVM——内存模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.java内存模型

JVM——内存模型,JVM+JUC,jvm

1.1 原子性

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm JVM——内存模型,JVM+JUC,jvm

1.2 问题分析

JVM——内存模型,JVM+JUC,jvm

这里与局部变量自增不同,局部变量调用iinc是在局部变量表槽位上进行自增。 

静态变量是在操作数栈自增。

这里的主内存和工作内存时再JMM里的说法。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvmJVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

 因为操作系统是时间片切换的多个线程轮流使用CPU.

1.3解决方法

JMM中通过synchronized(同步关键字)保证原子性。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

使用synchronized减i++和i--的分别的所有字节码指令作为一个整体运行。

使用synchronized加锁的力度最好大一点,只锁个i++就只有四条指令,不然增加时间。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

2.可见性

2.1退不出的循环

JVM——内存模型,JVM+JUC,jvm

运行发现停不下来了。

运行超过一秒之后就触发C2编译器进行优化了。run被读到了线程的局部变量表里面。

1s后再修改也看不见了。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

 JVM——内存模型,JVM+JUC,jvm

2.2解决方法

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

2.3可见性

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

volatile只适用于一个写线程和多个读线程的情况。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

println底层有synchronized关键字,也可以强制线程去到主存里面取值。

synchronized可以保证可见性和原子性。

3.有序性

3.1诡异的结果

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvmJVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

应该是指令顺序为了优化发生了改变导致ready=true时num还没获取到2。 

3.2解决方法

JVM——内存模型,JVM+JUC,jvm

@Outcome注解就是检查感兴趣的结果。

1或4就划分为可接受的,ok表示之中

0划分到另一个。

清除并重新编译

JVM——内存模型,JVM+JUC,jvm

生成一个源码jar包和一个压测入口jar包。 

JVM——内存模型,JVM+JUC,jvm JVM——内存模型,JVM+JUC,jvm

 运行测试包进行压测。

结果中有两种,一个是带了关闭了分层编译,还有一个是没带任何参数。

JVM——内存模型,JVM+JUC,jvm

 两种情况都有出现0的结果。

说明指令重排问题确实有。

解决方法就是使用volatie关键字。 

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

再次压测就不会有指令重排的问题了。

JVM——内存模型,JVM+JUC,jvm

3.3有序性理解

双重检测法创建单例 就需要volatile防止指令重排

JVM——内存模型,JVM+JUC,jvm

 JVM——内存模型,JVM+JUC,jvm

如果在创建的代码上加锁力度就太大了,创建该对象了,后续get该对象是不需要加锁的。

所以有了上面的双重判断,先判断是否实例为空,为空就加锁,加完锁再判断实例为空,任然为空就创建。

第一个if是为了提高效率,实例创建后,就不用一直获得锁对象。

第二个if是防止别的线程创建另一个实例。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm 0分配空间,3复制多一个引用进操作数栈4一个引用去调用构造方法7另一个引用交给了静态变量

JVM——内存模型,JVM+JUC,jvmt2直接返回了拿到了一个不完整的实例。

JVM——内存模型,JVM+JUC,jvm

3.4 happens-before

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvmJVM——内存模型,JVM+JUC,jvmJVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

就相当于打个标记,标记前改了值, 标记后看得见 

JVM——内存模型,JVM+JUC,jvm JVM——内存模型,JVM+JUC,jvm

4.CAS与原子类

4.1 CAS

CAS 是 Compare And Swap(比较并替换的缩写,当值为预期值的时候,就将该值替换为预期的值。

CAS 也是实现原子操作的一种方法。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm  

4.2乐观锁与悲观锁

JVM——内存模型,JVM+JUC,jvm

4.3原子操作类

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

测试结果为0。 

5.synchronized 优化(这个部分要先去看JUC)

JVM——内存模型,JVM+JUC,jvm

5.1轻量级锁

JVM——内存模型,JVM+JUC,jvmA有两次加锁,一次轻量锁,一次重量锁。升级过程就是锁膨胀。

轻量级锁的加锁过程。

线程和对象之间交换定情信物,对象给出了Mark World存在线程的锁记录里面,线程给出了锁记录地址。

Mark Word只有八个字节,解锁时才会将对象的Mark Word恢复。 

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm锁了A之后去访问B尝试锁B结果发现已经锁了,但是是自己上的锁所以还是可以访问B.

然后都访问完了之后就A和B都解锁。

解锁过程是把MarkWorld都还回去然后取出对象上的锁标记。 

JVM——内存模型,JVM+JUC,jvm

5.2锁膨胀

JVM——内存模型,JVM+JUC,jvm

 JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

 升级为重量级锁会把标记从01变成10,并在对象头里面加入重量级锁的指针,该指针用于线程1在解锁时唤醒阻塞中的线程。 

5.3重量锁_自旋

JVM——内存模型,JVM+JUC,jvm

这里线程2不会立刻 阻塞,阻塞需要把当前状态保存下来。

直接采用了自旋优化,先不停,不停重试,在阈值之内等到了对象解锁

JVM——内存模型,JVM+JUC,jvm 自旋失败 就进入阻塞状态了。JVM——内存模型,JVM+JUC,jvm

5.4 偏向锁

锁重入就是要锁不同的代码块时对同一个对象加锁。

JVM——内存模型,JVM+JUC,jvm

 JVM——内存模型,JVM+JUC,jvmJVM——内存模型,JVM+JUC,jvm

 5.5其它优化

上锁时间过长可能会导致轻量锁变成重量锁。

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm

JVM——内存模型,JVM+JUC,jvm文章来源地址https://www.toymoban.com/news/detail-679298.html

到了这里,关于JVM——内存模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM五大内存模型

    JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一个虚构出来的计算机,有着自己完善的硬件架构,如处理器、堆栈等。 Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码( 字节码 ),就可以在多种平台上不加

    2024年02月15日
    浏览(42)
  • JVM oop内存模型

    1、非数组对象 InstaceOopDesc 2、数组对象  arrayOopDesc         2.1 基本数据类型数组 typeArrayOopDesc         2.2 引用类型数组 objArrayOopDesc  3、MarkOopDesc         存放锁信息、分代年龄等 1、InstanceKlass是JVM中表示类的对象的数据结构。JVM在加载class时,会创建 instanceKlass ,表示其元

    2024年02月12日
    浏览(45)
  • 四、JVM-对象内存模型

    一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充 数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压缩技术 JDK1.6出现的 开启了指针压缩 什么时候指针压缩会

    2024年02月14日
    浏览(33)
  • JVM——内存模型

      这里与局部变量自增不同,局部变量调用iinc是在局部变量表槽位上进行自增。  静态变量是在操作数栈自增。 这里的主内存和工作内存时再JMM里的说法。  因为操作系统是时间片切换的多个线程轮流使用CPU. JMM中通过synchronized(同步)保证原子性。 使用synchronized减i+

    2024年02月11日
    浏览(28)
  • JVM之内存模型

    首先说明下 JVM内存模型 和 Java内存模型 这是两个不同的概念,不要搞混淆了。 JVM内存模型定义了Java程序在运行时如何分配、使用和释放内存,跟存储和执行相关,也就是常说的运行时数据区域。 Java内存模型(Java Memory Model,简称 JMM)是一种规范,定义了线程和主内存之间

    2024年02月08日
    浏览(31)
  • 认识JVM的内存模型

    从上一节了解到整个JVM大的内存区域,分为线程共享的heap(堆),MethodArea(方法区),和线程独享的 The pc Register(程序计数器)、Java Virtual Machine Stacks(Java虚拟机栈)、Native Method Stacks(本地方法栈),如下图 同时也大概了解到各个内存区域主要存储的数据类型,根据之前

    2024年02月10日
    浏览(35)
  • JVM内存模型详解

    JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的。     通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mikechen。   什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一个虚

    2023年04月13日
    浏览(61)
  • JVM学习05:内存模型

    很多人将 java 内存结构 与 java 内存模型 傻傻分不清,java 内存模型是 **Java Memory Model(JMM)**的意思。 JMM 定义了一套在多线程读写共享数据时(成员变量、数组)时,对数据的可见性、有序性、和原子性的规则和保障。 原子性是指一个操作是 不可中断 的。即使在多个线程一

    2024年02月04日
    浏览(39)
  • 进阶课程1:jvm内存模型

    在Java中,局部变量和成员变量的区别如下: 定义的位置不同:成员变量定义在类中,而局部变量定义在方法中或者方法的声明上。 在内存中的位置不同:成员变量存储在堆内存的对象中,而局部变量存储在栈内存的方法中用。 生命周期不同:成员变量随着对象的创建而存在

    2024年02月11日
    浏览(41)
  • Jvm学习笔记(一)内存模型

    java不需要用户手动去管理内存的释放,这大大解放了程序员的心智负担,jvm运行的核心绕不开他的内存模型,本章着重于jvm的内存模型分析。 程序计数器是一块较小的内存区域,主要作用是确定下一条需要执行的字节指令(java执行的是字节指令),它是程序控制流的指示器

    2023年04月14日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包