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管的是"多线程环境下,怎么跑才对"。

相关推荐
李日灐2 小时前
改造红黑树实现封装 map/set:感受C++ 标准容器的精妙设计与底层实现
开发语言·数据结构·c++·后端·算法·红黑树
李日灐2 小时前
【优选算法1】双指针经典算法题
数据结构·c++·后端·算法·刷题·双指针
技术钻石流2 小时前
面向“传统程序员”的端到端 10x Vibe Coding 指南(大型需求) - 从面向业务开发转向面向“Agent 员工”开发
前端·后端·ai编程
xiao_juzi2 小时前
OpenClaw 环境变量配置完全指南
后端
2501_921649492 小时前
免费港股实时行情 API:功能、性能与接入指南
开发语言·后端·python·金融·restful
程序员柳2 小时前
智能学生管理系统:Spring Boot3+Vue3 前后端分离开发与 Docker 部署
spring boot·后端·docker
工边页字2 小时前
AI产品中的长期记忆和短期记忆是什么,你知道吗?
前端·人工智能·后端
毕设源码-钟学长2 小时前
【开题答辩全过程】以 基于SpringBoot的健康系统为例,包含答辩的问题和答案
java·spring boot·后端
badhope2 小时前
Python 库全景图:核心工具与最佳实践(小白也能看懂版)
后端·python