Java内存模型与JVM运行时数据区的区别详解
作者:Java_老男孩 发布时间:2023-11-24 13:29:08
首先,这两者是完全不同的概念,绝对不能混为一谈。
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区。
来源:https://blog.51cto.com/14230003/2443407


猜你喜欢
- 一、背景今天心血来潮,准备测试一下项目中 logback 的自动刷新功能,但是测试时发现并不生效。logback 的配置如下:<con
- 1. 快速创建maven管理的SpringBoot项目1、访问 http://start.spring.io/2、 选择构建工具Maven
- 1.问题引出源码: public static void main(String[] args) { List&l
- spring cloud 配置中心native配置1、pom文件添加依赖<dependency> &l
- 因为工作原因需要读取json文件,最先是使用url方式不符合要求pass。又使用本地方式读取。记录一下方便后期查看。 注:因为资料都是从网上
- 目录前言实践部分测试部分总结前言今天跟小伙伴们分享一个实战内容,使用Spring Boot+Shiro实现一个简单的Http认证。场景是这样
- 出处:https://www.cnblogs.com/SunSpring作为初学者配置maven一般网上搜索。然后你就看到各种配置文件片段,
- java模拟实现图书检索系统 (基础版),供大家参考,具体内容如下练习实现3个简单的功能,没有优化,可以根据需求,自行添加想要实现的功能。B
- 本文实例讲述了Android自定义控件样式的方法。分享给大家供大家参考,具体如下:Android控件样式自定义是用定义在drawable文件
- 前言大家应该都用过synchronized 关键字加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行,有什
- 集合、数组都是对多个数据进行存储操作(主要是内存层面存储)的结构,简称Java容器。数组的特点1.数组初始化以后,长度确定不可变2.数组定义
- 首先什么是注解?@Override就是注解,它的作用是:1、检查是否正确的重写了父类中的方法。 2、标明代码,这是一个重写的方法。1、体现在
- 前言空间分配要点有:一是空间分配的连续性;二是动态内存申请;三是防止程序执行中出现异常错误。提示:开始讲解了嗷~后续会根据精力持续更新嗷!!
- 前言首先,我们要讲的是JVM的垃圾回收机制,我默认准备阅读本篇的人都知道以下两点:JVM是做什么的Java堆是什么因为我们即将要讲的就是发生
- C#连接本地.mdf文件:项目中右键点击,新增——数据——基于服务的数据库,项目下直接生成.mdf数据库文件,后台(数据库的写入用参数传递)
- Queue接口先看下Queue的继承关系和其中定义的方法:Queue继承自Collection,Collection继承自Iterable。
- 本文实例讲述了C#画笔Pen绘制自定义线的帽子。分享给大家供大家参考。具体如下:using System;using System.Coll
- 前言 因为自己在做的一个小软件里面需要用到从A-Z排序的ListView,所以自然而然的想到了微信的联系人,我想要的就是那样的效果。本来没
- C# DateTime与时间戳的相互转换,包括JavaScript时间戳和Unix的时间戳。1. 什么是时间戳首先要清楚JavaScript
- 实现手机电话状态的监听,主要依靠两个类:TelephoneManger和PhoneStateListener。 TelephonseMang