一文拿捏对象内存布局及JMM(JAVA内存模型)
1 JMM(Java Memory Model)
1 概述
Java内存模型(Java Memory Model简称JMM)是一种抽象的概念,并不真实存在,它描述的一组规则或者规范。通过这些规则、规范定义了程序中各个变量的访问方式。jvm运行的程序的实体是线程,而每个线程运行时,都会创建一个工作内存(也叫栈空间),来保存线程所有的私有变量。而JMM内存模型规范中规定所有的变量都存储在主内存中,而主内存中的变量是所有的线程都可以共享的,而对主内存中的变量进行操作时,必须在线程的工作内存进行操作,首先将主内存的变量copy到工作内存,进行操作后,再将变量刷回到主内存中。所有线程只有通过主内存来进行通信。
-
JMM描述的是对程序中变量访问方式的规则规范
-
JVM运行程序的实体是线程,每个线程有其工作空间,用于存储私有变量
-
JMM规定所有的变量需存储在主内存中,主内存的变量是所有线程共享的
-
对主内存的变量操作,需要将主内存变量copy到线程的工作空间
-
在线程工作空间操作完之后,刷回主内存
2 可见性,原子性与有序性
1 原子性
原子性指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程给打断。
在java中,对基本的数据类型的操作都是原子性的操作,但是要注意的是对于32位系统的操作对于long、double类型的并不是原子性操作(对于基本数据类型,byte,short,int,float,boolean,char读写是原子操作)。因为对于32位的操作系统来说,每次读写都是32位,而doubel、long则是64位存储单位。就会导致一个线程操作完前面32位后,另一个线程刚好读到后面的32位,这样一来一个64位被两个线程分别读取。
2 可见性
可见性指的是当一个共享变量被一个线程修改后,其他线程是否能够立即感知到。对于串行执行的程序是不存在可见性,当一个线程修改了共享变量后,后续的线程都能感知到共享变量的变化,也能读取到最新的值,所以对于串行程序来讲是不存在可见性问题。
对于多线程程序,就不一定了,前面分析过对于共享变量的操作,线程都是将主内存的变量copy到工作内存进行操作后,在赋值到主内存中。这样就会导致,一个线程改了之后还未回写到主内存,其余线程就无法感知到变量的更新,线程之间的工作内存是不可见的。另外指令重排序以及编译器优化也会导致可见性的问题。
3 有序性
有序性是指对于单线程的代码,我们总是认为程序是按照代码的顺序进行执行,对于单线程的场景这样理解是没有问题,但是在多线程情况下, 程序就会可能发生乱序的情况,编译器编译成机器码指令后,指令可能会被重排序,重排序的指令并不能保证与没有排序前的保持一致。
在java程序中,倘若在本线程内,所有的操作都可视为有序性,在多线程环境下,一个线程观察另外一个线程,都视为无顺序可言。
3 JMM如何解决原子性&可见性&有序性
1 原子性问题
除了jvm自身提供的对基本类型的原子性操作以外,可以通过synchronized和Lock实现原子性。synchronized与lock在同一时刻始终只会存在一个线程访问对应的代码块。
2 可见性问题
volatile关键字保证了可见性。当一个共享变量被volatile修饰时,它会保证共享变量修改的值立即被其他线程可见,即修改的值立即刷新到主内存,当其它线程去需要读取变量时,从主内存中读取。synchronized和Lock也保证了可见性。因为同一时刻只有一个线程能访问同步代码块,所以是能保证可见性。
3 有序性问题
volatile关键字保证了有序性,synchronized和Lock也保证了有序性(因为同一时刻只允许一个线程访问同步代码块,自然保证了线程之间在同步代码块的有序执行)。
2 对象内存布局
1 对象头区
-
对象标记
-
锁标记
-
是否偏向
-
hashCode值
-
对象分代年龄 ✨对象头Mark区四位二进制:0000-1111 --> 最多15轮GC
-
-
类元指针: 指向方法区中的类元信息 java底层实现反射的基础
-
数组长度
2 实例数据区
真正属性信息的值
3 对齐填充区
为了保证对象是8字节的倍数
相关文章:

一文拿捏对象内存布局及JMM(JAVA内存模型)
1 JMM(Java Memory Model) 1 概述 Java内存模型(Java Memory Model简称JMM)是一种抽象的概念,并不真实存在,它描述的一组规则或者规范。通过这些规则、规范定义了程序中各个变量的访问方式。jvm运行的程序的实体是线程,而每个线程运行时&am…...

Android组件通信——ActivityGroup(二十五)
1. ActivityGroup 1.1 知识点 (1)了解ActivityGroup的作用; (2)使用ActivityGroup进行复杂标签菜单的实现; (3)使用PopupWindow组件实现弹出菜单组件开发; 1.2 具体…...
js的继承的方式
1.对象冒充继承 使用 bind,call,apply 解决构造函数属性的继承 缺点:不能继承原型上的属性和方法 //-------------父类-------------function Person(name, age, sex) {this.name name;this.age age;this.sex sex;}Person.prototype.run function () {console.log(我${this…...
聊聊HttpClient的重试机制
序 本文主要研究一下HttpClient的重试机制 HttpRequestRetryHandler org/apache/http/client/HttpRequestRetryHandler.java public interface HttpRequestRetryHandler {/*** Determines if a method should be retried after an IOException* occurs during execution.**…...

北邮22级信通院数电:Verilog-FPGA(4)第三周实验:按键消抖、呼吸灯、流水灯 操作流程注意事项
北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.注意事项 二.按键消抖 2.1 LED_deboun…...

Ghidra101再入门(上?)-Ghidra架构介绍
Ghidra101再入门(上?)-Ghidra架构介绍 最近有群友问我,说:“用了很多年的IDA,最近想看看Ghidra,这应该怎么进行入门?“这可难到我了。。 我发现,市面上虽然介绍Ghidra怎么用的文章和书籍很多&…...

Vue3路由引入报错解决:无法找到模块“xxx.vue”的声明文件 xxx隐式拥有 “any“ 类型。
这类情况应该遇见过吧,这是因为 TypeScript只能理解 .ts 文件,无法理解 .vue 文件。 解决方法:在项目的根目录或者src文件夹下创建一个后辍为 文件名.d.ts 的文件,并写入一下内容: declare module *.vue {import { …...

基于若依ruoyi-nbcio支持flowable流程分类里增加流程应用类型
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 主要考虑到流程分很多种,普通的是OA流程,还有自定义业务流程,钉钉流程等…...

JS之同步异步promise、async、await
promise异步操作 Promise是异步编程的一种解决方案 JavaScript异步与同步解析 学习promise前我们先来了解下什么是异步? 基本概念: 消息队列中的任务分为宏任务与微任务;调用栈也可以称为主线程 首先我们要知道js是单线程语言,也就是说…...
【OpenCV • c++】自定义直方图 | 灰度直方图均衡 | 彩色直方图均衡
文章目录 一、什么是直方图二、自定义直方图三、灰度直方图均衡四、彩色直方图均衡一、什么是直方图 直方图广泛应用于很多计算机视觉处理当中。通过标记帧与帧之间显著的边缘和颜色的变化,可以检测视频中的场景变化。在每个兴趣点设置一个有相似特征的直方图所构成的“标签”…...
el-tree目录和el-table实现搜索定位高亮方法
需求:el-tree目录实现搜索查询el-table表格项,双击表格项根据yiZhuMLID||muLuID定位el-tree目录,并且高亮展示在可视化区域内,再重新根据el-tree目录的yiZhuMLID搜索刷新el-table表格,定位且高亮展示相对应的yiZhuMLID…...
linux常用指令
基础命令 cd:用于切换目录。例如,要从当前目录切换到/home/user目录,可以使用命令“cd /home/user”。ls:用于列出目录内容。例如,要列出当前目录的内容,可以使用命令“ls”。mkdir:用于创建目…...

C语言,指针的一些运算
若创建一个数组:int arr[10] 0; 用指针变量来储存数组首元素的地址:int* p arr,这里arr是数组名,表示首元素地址。 若p p 1或者p之后p本来指向数组首元素地址,就变成了指向第二个元素的地址,p n即指向第n 1个地…...

iPhone 如何强制重启
参考iPhone的官方使用手册 传送门 尤其当 iPhone 未响应,也无法将其关机再开机,此方法最有效: 按住调高音量按钮,然后快速松开。按住调低音量按钮,然后快速松开。按住侧边按钮。当 Apple 标志出现时,松开侧…...
数据结构--单链表操作
1.单链表的创建(带头结点) #include<stdlib.h> #define ElemType int typedef struct {//定义一个结点ElemType data;struct STU* next; }STU,*LinkList; bool InitList(LinkList& L) {L (STU*)malloc(sizeof(STU));//创建头结点if (L NUL…...

AlmaLinux (兼容centos)安装Geant4与ROOT
AlmaLinux 介绍 AlmaLinux OS 是一个开源、社区驱动的 Linux 操作系统,它填补了因 CentOS 稳定版本停止维护而留下的空白,同时更加强大。 安装 AlmaLinux 这个我用的是 windows 子系统进行安装 首先打开微软商店,然后搜索AlmaLinux&#…...
FPGA面试题(2)
一.同步复位和异步复位 同步复位:当clk有效时,复位才有效。优点:有利于时序分析,防止毛刺现象出现。缺点:复位信号必须大于时钟周期,大部分逻辑器件中D触发器都只有异步复位端口,需要在寄存器数…...
【C++ Primer Plus学习记录】指针——使用new来创建动态数组
目录 1.使用new创建动态数组 2.使用动态数组(如何使用指针访问数组元素) 如果程序只需要一个值,则可能会声明一个简单变量,因为对于管理一个小型数据对象来说,这样做比使用new和指针更简单。通常,对于大型…...

移动app广告变现,对接广告联盟还是选择第三方聚合广告平台?
作为互联网广告的载体,APP天生就比线下传统广告位更具优势,不受地域限制可以辐射到地球上的每一个角落,可以让广告获得更广的覆盖面。通过丰富的广告形式,精准的目标用户画像,也可以更好地实现品牌广告或效果广告的投放…...

ARM 按键控制 LED灯,蜂鸣器,风扇
main.c: #include "uart.h" #include "key_it.h" int main() {all_led_init();uart4_init();//串口初始化//中断初始化key_it_config();key3_it_config();buzzer_init();fan_init();while(1){//保证主程序不结束}return 0; }src/key_it.c: #include"…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...