当前位置:网站首页 > Java基础 > 正文

jvm内存模型和java内存模型(java内存模型jmm)



总结

JMM和JVM的关联


1、JAVA内存模型(JMM)

===============

1.1、操作系统内存模型解决的问题

=================

在现代计算硬件体系中,CPU的数据处理速度远比从内存条读写数据的速度要快,为了更好地利用CPU的运算能力,每个CPU都配备了寄存器和CPU缓存来提高IO吞吐,降低CPU等待数据的耗时。

既然是高速缓存,其高成本就导致存储空间必然有限,也就不会将全量数据都装载,因此只会将CPU当下计算所需的数据副本拷贝到高速缓存中。虽然提高了CPU读写数据的IO吞吐,也带来的数据不一致问题。

对于数据不一致问题,不同的操作系统有不同的系统级指令的解决方案,来约束线程的数据在何时从主内存读取,何时写入主内存。

1.2、JAVA内存模型解决的问题


市面上的操作系统百花齐放,而Java作为一个跨平台的语言,势必要为用户屏蔽底层细节。因此在操作系统内存模型的基础上,对共性抽象提出了Java 内存模型。

Java内存模型

JMM规定:

1、主内存:也就是虚拟机内存(可以类比理解为物理硬件的内存条),所有共享变量均在主内存存储

2、工作内存:JMM 的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器等。每个线程均有自己的工作内存,其中存储的是线程工作所需的主内存数据的拷贝副本。

3、线程无法获取其它线程的工作内存的数据,因此线程通信的方式有两种,其一是共享内存传递数据,其二是消息通信。

Java内存模型,也即在Java虚拟机中实现的内存模型,约束了将变量存储到内存和从内存中取出变量这样的底层细节。具体分为以下三个层面

原子性

指的是一组指令在cpu执行过程中,cpu不会被中断,也即这一组指令要么不执行,要么执行且全部完成。

有序性

在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序,可能会打乱代码执行顺序。

A、指令重排需要满足两个条件

在不改变单线程程序语义的前提下

存在数据依赖关系的不允许重排序

B、重排序分三种类型

编译期的重排序。从java源码到编译成class文件,可以重新安排语句的执行顺序。

CPU指令级并行的重排序。处理器可以改变语句对应机器指令的执行顺序,多条指令可以并行执行。即时编译器JIT也会做指令重排

内存系统的重排序。线程工作内存与主内存同步延迟,这使得加载和存储操作看上去可能是在乱序执行。

从 java 源代码到最终实际执行的指令序列,会分别经历下面三种重排序:

C、禁止重排序的手段——内存屏障(memory barrier)

内存屏障是一个CPU指令,能达到两个效果:

确保一些特定操作执行的顺序,禁止指令重排序

影响数据可见性,写屏障会将线程工作内存的数据强制写入主内存,读屏障会强制从工作内存读取数据

可见性

指的是多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

1、保证可见性的手段——happens-before原则

如果 A happens-before B,那么 Java 内存模型则保证: A 操作的结果将对 B 可见,且 A 的执行顺序排在 B 之前

  • 程序顺序规则:一个线程中的每个操作,happens- before 于该线程中的任意后续操作。
  • 监视器锁规则:对一个监视器锁的解锁,happens- before 于随后对这个监视器锁的加锁。
  • volatile 变量规则:对一个 volatile 域的写,happens- before 于任意后续对这个 volatile 域的读。
  • 传递性:如果 A happens- before B,且 B happens- before C,那么 A happens- before C。

2、 JAVA虚拟机模型(JVM)

=================

jvm规定的虚拟机内存分配模型

JDK8按照JVM规范的具体实现

 程序计数器


程序计数器是描述CPU运行的存储结构。CPU自带的存储介质是寄存器,CPU运行计算所需的任何数据都需要从寄存器获取。每个线程在创建后,都会产生自己的程序计数器和栈帧。

由于CPU的时间片轮转特性,一个线程承载的任务可能在一个CPU时间片内无法完成,此时操作系统会会随机选择下一个线程执行,因此需要程序计数器存放执行指令的偏移量和行号指示器等,线程执行或恢复都要依赖程序计数器。

生命周期:和线程同生共死,线程创建时诞生,线程结束时消亡

虚拟机栈


虚拟机栈是描述方法执行的存储结构,用后进先出的栈结构,按照方法执行顺序记录方法地址。每个线程的虚拟机栈的栈顶指示的就是所有活动方法列表。

生命周期:和线程同生共死,线程创建时诞生,线程结束时消亡

本地方法栈


本地方法栈和虚拟机栈实现的功能相同,只不过虚拟机栈是为虚拟机执行Java方法(也就是字节码)服务,本地方法栈则为虚拟机使用到的Native方法服务。

生命周期:和线程同生共死,线程创建时诞生,线程结束时消亡

堆内存


对象创建所需申请的空间,不要求磁盘的物理连续性,只要求逻辑连续性即可,所有线程共享的存储区域

方法区


方法区是JVM虚拟机规范,也称堆外内存。方法区是所有线程共享的存储区域,存放数据如下:类信息、常量、静态变量、即时编译器编译后的代码,其中常量存储在运行时常量池中。

当.java编译成.class文件后,除了会生成类名、字段、方法等信息外,还有就是常量信息(包含这个java类定义的各种常量字符串和符合引用),这个常量信息就会被放到运行时常量池中。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

到此这篇jvm内存模型和java内存模型(java内存模型jmm)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 单向链表反转java实现(编写实现单向链表逆转的程序)2025-03-22 11:54:09
  • java date工具类(java中dateformat类)2025-03-22 11:54:09
  • 华为java面试题及答案(华为java面试题目)2025-03-22 11:54:09
  • java字符串转map集合(java字符串转char数组)2025-03-22 11:54:09
  • java面试题详解(java面试题带答案)2025-03-22 11:54:09
  • java spring入门(java spring 用法)2025-03-22 11:54:09
  • java调用dll动态库 java接收char*乱码(java调用dll实例)2025-03-22 11:54:09
  • java入门教程自学网(java 入门教程)2025-03-22 11:54:09
  • java课程 在线(java教程视频免费)2025-03-22 11:54:09
  • java和爬虫有什么区别(爬虫和java的区别)2025-03-22 11:54:09
  • 全屏图片