Java面试被问:跟我讲下JVM和JMM?

面试官:你给我讲下JVMJMM

面试者:JVM就是我们的虚拟机,然后JMM我记得是并发编程如何保证数据可见性跟有序性。

面试官:具体点呢?

面试者:诶......

我来给你讲下吧:

先说 JVM(Java虚拟机)

JVM在跑起来的时候,会把操作系统给它的内存,划分成几个关键区域,每个地方放不同的东西,并且针对这些区域进行清理维护:

new 出来的所有对象和数组 ,几乎都放在这里。它是垃圾回收器主要打扫的区域这是最大、最重要的一块所有线程共享

还有像 方法区(JDK8后叫元空间) 也是所有线程共享 。这里存放加载的类信息、常量、静态变量这些"模板"性质的东西。

还有线程私有的 虚拟机栈 本地方法栈 程序计数器等等

简单总结JVM: 它是个具体的执行引擎和内存管理者,负责把Java代码跑起来,管着内存的"物理"划分------哪里放对象、哪里放局部变量、垃圾怎么清理。

但是有个问题。上面提到的"堆"是共享的,意味着所有线程都能去访问里面的对象。但现代计算机为了快,CPU有高速缓存,编译器和处理器还会优化指令顺序(指令重排序)。这就会导致三个核心问题:

可见性问题有序性问题、 原子性问题

JMM(Java Memory Model), Java 内存模型就是为了定义一套规则,来解决这些问题。

JMM规定所有变量都存储在主内存(可以粗略理解为堆)中,每个线程有自己的工作内存(涵盖了缓存、寄存器等)。线程不能直接读写主内存,只能操作自己工作内存中的副本,然后再同步回主内存。

关键在于它定义的 happens-before 规则和提供的关键字:

happens-before 规则 是判断操作是否"可见"的核心原则,就是如果A操作 happens-before B操作,那么A做的所有改动,对B来说都是一定可见的。常见规则包括:程序顺序规则、监视器锁规则、传递性规则等等

然后就是几个关键字

  • synchronized:当你要进入同步块时,JMM要求你先清空工作内存,从主内存重新加载变量。退出时,必须把修改过的变量刷回主内存。这样,就同时保证了原子性、可见性和有序性
  • volatile:它保证两件事:1)每次读都从主内存读,每次写都立刻刷回主内存(保证可见性 )。2)禁止指令重排序(保证有序性 )。但它不保证原子性
  • final:被final修饰的字段,一旦在构造器中初始化完成,并且构造过程没有"this"引用逸出,那么其他线程就能看到它的正确值。

总结下

  • JVM是"实现者"和"平台" 。它具体负责内存怎么划分(堆、栈...),代码怎么执行,垃圾怎么回收。它是一个运行时实例
  • JMM是"规范"和"契约" 。它定义了在多线程这个特定场景下,数据应该如何被访问和同步,以保证正确性。它是一套规则

所以,JVM管的是"程序怎么跑",JMM管的是"多线程环境下,怎么跑才对"。

相关推荐
GreenTea13 小时前
GrokBot 核心成员 Lauren Tan:每月交付 2000 个 PR 的人,是怎么用 AI 的
前端·后端·架构
码事漫谈13 小时前
FDE:一个缩写,两种命运
后端
名字还没想好☜14 小时前
Go context.AfterFunc 实战(Go 1.21):context 一取消就自动跑清理,告别手写 goroutine 监听 Done
后端·golang·go
明月_清风15 小时前
为什么最近开始关注 JEV?几个实战案例告诉你答案
人工智能·后端
GetcharZp16 小时前
5 分钟拥有自己的 S3:RustFS 上手(MinIO 的 Rust 替代,Apache 2.0 可商用)
后端
行百里er17 小时前
Redis 版本演进、新特性与协议那些事儿
redis·后端
Joy T17 小时前
Spring AI 2.0 Agent 进阶:Memory、State 与 Context Engineering 常见技术全景
java·人工智能·后端·spring·agent入门·agent state
打工仔折腾 AI18 小时前
FastAPI 从本机到生产服务器:Nginx+Gunicorn+Uvicorn 完整部署实录
人工智能·后端·python·nginx·fastapi·gunicorn
IT_陈寒18 小时前
Java空指针这次真把我坑惨了
前端·人工智能·后端