java面试一日一题:java内存模型
问题:请讲下java内存模型?
分析:该问题比较容易和jvm内存区域(java内存结构)这样的问题混淆,其实他们是两个概念,jvm内存区域指的是运行时的几块数据区域,包括堆、方法区、虚拟机栈、本地方法栈、程序计数器,强调的是在java程序运行的时候,内存是怎么划分的;而内存模型是另外的一个概念。
回答要点:
主要从以下几点去考虑,
1、java内存模型的作用,保证程序执行的可见性、有序性、原子性;
2、内存模型定义了什么,内存模型定义了多线程读写共享内存的规范;
3、内存模型怎么实现多线程共享变量的读写;
java内存模型简称JMM,是一种规范,通过这些规范定义java程序中各个变量的访问方式,解决并发编程中可能出现的线程安全问题。jvm运行程序的实体是线程,每个线程创建时jvm都会为其创建一个工作内存,用于存放线程私有的数据;Java内存模型规定所有的变量均保存在主内存中,主内存是共享内存,所有的线程都可以访问,但对变量的所有操作(包括读取赋值)都在工作内存中进行,线程无法直接操作主内存中的变量,所以就有了JMM。
主内存
主要存储的是Java实例对象,所有线程创建的实例对象都在主内存中,不管是成员变量还是在方法中创建的局部变量,同时也包含类信息、常量(static final)、静态变量(static)。由于主内存是共享区域,所以多个线程对同一个变量访问就会有线程安全问题;可以把主内存想象为java内存区域的堆、方法区
工作内存
主要存储当前线程正在执行的方法的所有本地变量(工作内存中存储着主内存中变量的副本),工作内存只对当前线程可见,其他线程无法访问当前线程的变量;可以把工作内存想象为Java内存区域的虚拟机栈、本地方法栈、程序计数器;是在java程序运行时的内存;
一个实例对象中的成员方法,如果方法中包含本地变量是基本数据类型(8种,boolean byte short int long double float char),这些基本类型的变量存储在工作内存中;如果本地变量是引用类型,那么该变量的引用存储在工作内存中,对象实例则存储在主内存中,对应对象实例中的成员变量不论是基本类型还是引用类型都存储在主内存中;
例,
public class Test{ private void method(){ A ma=new A(); int a=0; } } public class A{ private int a; private Integer aa; }
上面的方法method中的ma会存储在工作内存中,a存储在工作内存,而new A()生成的实例存储在主内存中,包括实例中的a也是存储在主内存中;
在Java中可以依靠volatile和synchronized关键字来保证可见性、有序性、原子性,除此之外还定义了一套happens-before原则来保证多线程操作时的可见性、有序性、原子性;
程序顺序原则,在一个线程内必须保证语义串行性,也就是按照代码顺序执行;
锁原则,加锁操作必然发生在解锁操作之后(同一把锁);
volatile原则,volatile的写先发生于volatile的读;
。。。
先写下分析思路,后续补充详细内容,有不当之处欢迎指正!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)