Java内存模型与JVM运行时数据区的区别详解

所属分类: 软件编程 / java 阅读数: 90
收藏 0 赞 0 分享

首先,这两者是完全不同的概念,绝对不能混为一谈。

1.什么是Java内存模型?

Java内存模型是Java语言在多线程并发情况下对于共享变量读写(实际是共享变量对应的内存操作)的规范,主要是为了解决多线程可见性、原子性的问题,解决共享变量的多线程操作冲突问题。

多线程编程的普遍问题是:

  • 所见非所得
  • 无法肉眼检测程序的准确性
  • 不同的运行平台表现不同
  • 错误很难复现

故JVM规范规定了Java虚拟机对多线程内存操作的一些规则,主要集中体现在volatile和synchronized这两个关键字。

  • volatile 是JVM提供的对共享变量在多线程读写时的可见性保证,主要作用是对volatile修饰的共享变量禁止被缓存(这里跟CPU的高速缓存和缓存一致性协议有关),不做重排序(重排序:在CPU处理速度远大于内存读写速度的现状下为了提高性能而进行的优化),但是并不保证共享变量操作的原子性。
  • synchronized 是JVM提供的锁机制,通过锁的特性和内存屏障保证锁住区域操作的原子性、可见性、有序性。
  • 锁争抢的是对象(static锁的是类对象,非static锁的是当前对象,即this,锁方法块锁的是自定义对象)在堆内存中对象头的一块内存的“主权”,只有一个线程能获取该“主权”,即排他性,通过锁的排他性保证对锁住区域的操作的原子性
  • 通过在代码前后加入加载屏障(Load Barrier)和存储屏障(Store Barrier),能保证锁住代码块或者方法中对共享变量的操作的可见性
  • 通过在代码前后加入获取屏障(Acquire Barrier)和释放屏障(Release Barrier),能保证锁住代码块或者方法中对共享变量的操作的有序性

2.什么是JVM运行时数据区?

JVM运行时数据区,是Java虚拟机在运行时对该Java进程占用的内存进行的一种逻辑上的划分,包括方法区、堆内存、虚拟机栈、本地方法栈、程序计数器。这些区块实际都是Java进程在Java虚拟机的运作下通过不同数据结构来对申请到的内存进行不同使用。

  • 方法区:JVM用来存储加载的类信息、常量、静态变量、编译后的代码等数据。不同虚拟机有不同的实现,oracle的HotSpot在Java7中方法区放在永久代,Java8中方法区放在元空间,并通过GC机制来管理。
  • 虚拟机栈:每个线程私有的空间,由多个栈帧组成,一个方法对应一个栈帧,栈帧包括局部变量表、操作数栈、动态链接、方法返回地址、附加信息等。栈内存默认最大1M,超出跑出StackOverFlowError。
  • 本地方法栈:类似虚拟机栈,是为虚拟机使用native本地方法而准备的。具体实现由虚拟机厂商来实现。HotSpot虚拟机中实现与虚拟机栈一致,同时超出大小抛StackOverFlowError。
  • 程序计数器:记录当前线程执行字节码的位置,存储的是字节码指令地址,如果native方法,则为空。CPU同一时间只能执行一条线程中的指令,线程切换后通过程序计数器来恢复正确的执行位置。
  • 堆内存:所有线程都可以访问修改,存放的是对象实例,是数据区中占用空间最大的部分,在HotSpot虚拟机中分为新生代和老年代,新生代又分为Eden区和Survivor0区、Survivor1区。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

Java基于反射机制实现全部注解获取的方法示例

这篇文章主要介绍了Java基于反射机制实现全部注解获取的方法,结合实例形式分析了java反射机制获取注解的具体实现方法与操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

Java 信号量Semaphore的实现

这篇文章主要介绍了Java 信号量Semaphore的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

eclipse+maven+spring mvc项目基本搭建过程

这篇文章主要介绍了eclipse+maven+spring mvc项目基本搭建过程,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Spring boot集成swagger2生成接口文档的全过程

这篇文章主要给大家介绍了关于Spring boot集成swagger2生成接口文档的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

Java冒泡排序法和选择排序法的实现

这篇文章主要介绍了Java冒泡排序法和选择排序法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring Cloud Alibaba教程之Sentinel的使用

这篇文章主要介绍了Spring Cloud Alibaba教程之Sentinel的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Josephus环的四种解法(约瑟夫环)基于java详解

这篇文章主要介绍了Josephus环的四种解法(约瑟夫环)基于java详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Java继承Thread类创建线程类示例

这篇文章主要介绍了Java继承Thread类创建线程类,结合实例形式分析了java线程操作相关使用技巧与注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

Java使用Callable和Future创建线程操作示例

这篇文章主要介绍了Java使用Callable和Future创建线程操作,结合实例形式分析了java使用Callable接口和Future类创建线程的相关操作技巧与注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

springBoot使用JdbcTemplate代码实例

这篇文章主要介绍了springBoot使用JdbcTemplate代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多