图文示八股

JVM

JVM内存模型

存储
存储
子区域
JVM内存模型
线程共享区域
线程私有区域
方法区
程序计数器: 指向当前执行的字节码地址, 线程切换后会恢复
虚拟机栈: 存放运行时栈信息
本地方法栈: 调用native方法如c/c++时使用
对象实例和数组
垃圾回收GC主要区域
类信息,常量,静态变量,JIT编译后的代码
运行时常量池

栈和堆区别

栈:

  • 线程私有,线程安全
  • 每个线程创建时分配独立的栈
  • 存储函数方法执行时的栈帧
  • 自动管理,与作用域绑定
  • 后进先出,无内存碎片问题

堆:

  • 线程共享,非线程安全
  • JVM启动时创建,整个JVM进程只有一个堆
  • 存储对象实例和数组
  • 垃圾回收器GC管理
  • 可能有内存碎片问题

Java对象结构

  • 对象头
  • 实例数据,涉及字段重排:基本类型优先 long/doulble > int/float > short/char > boolean/byte > 引用类型;父类字段 > 子类字段
  • 对齐填充:对象大小必须是8字节的倍数

判断对象可以被回收

通过 “可达性分析算法” 判断对象是否能关联到根对象;不可达对象进入回收候选队列,若未通过finalize()自救,且无特殊引用保护,则最终会被 GC 回收。

强引用:Java默认,只要存在就不会回收

软引用(SoftReference):内存不足时才会回收,适合缓存;

弱引用(WeakReference):下次 GC 时必然回收,适合临时关联;

虚引用(PhantomReference):仅用于跟踪对象回收过程,无法通过虚引用获取对象。

垃圾回收算法

标记-清除算法
  1. 标记: 从GC Roots开始,标记所有可以访问的对象
  2. 清除: 遍历整个堆,释放未被标记的对象

优点: 实现简单
缺点: 内存碎片,遍历整个堆效率低

标记-复制算法
  1. 将堆内存划分为两个大小相等的区域(如 From 区和 To 区),只使用其中一个区域(From 区);
  2. 标记: 标记 From 区中所有可达对象
  3. 复制: 将所有标记对象复制到 To 区,并更新引用
  4. 清空 From 区,交换 From 和 To 区的角色

优点: 避免内存碎片,效率高
缺点: 内存利用率低:堆内存只能使用一半

标记-整理算法
  1. 标记: 与 “标记-清除” 相同,标记所有可达对象
  2. 将所有可达对象向堆内存的一端移动,集中排列,然后直接清理边界外的所有内存(未标记对象)

优点:解决内存碎片,效率比 “标记-复制” 高
缺点:移动对象,比 “标记-清除” 效率低

分代收集算法

核心思想:基于 “对象存活周期不同” 的观察(大部分对象存活时间短,少数对象存活时间长),将堆内存划分为新生代和老年代,针对不同代采用不同算法:

新生代:对象存活率低,用标记-复制算法(高效且无碎片)

老年代:对象存活率高,用标记-清除或标记-整理算法(避免频繁复制的高成本)

几乎所有现代 JVM(如 HotSpot)的默认回收策略
CMS 新生代:复制 ; 老年代: 标记清除
G1 新生代:复制 ; 老年代: 标记整理和复制混合

如何排查和解决JVM内存泄漏问题?

判断指标:

  • 程序频繁抛出OOM异常
  • GC后内存长时间不下降
  • GC频繁触发,开启 GC 日志:-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log

捕获堆内存快照:

  • 使用 jmap 生成快照:
    jps  # 查看服务进程ID,假设为12345
    jmap -dump:format=b,file=/tmp/product-heap-before-oom.hprof 12345
    
  • 通过 JVM 参数自动生成快照:
    -Xms2g -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/product-heap.hprof
    

分析内存快照:

  • 识别异常对象(数量多,生命周期过长)
  • 检查对象引用链

修复代码:

  • 静态集合未清理(如:static final Map<Long, Product> productCache 不断添加元素)
  • 资源未释放(IO流)
  • 线程泄漏

工具链:jmap(生成快照) + MAT(分析快照) + GC 日志(辅助验证)。

JVM 内存泄漏分析案例

Cloud

Nacos注册中心宕机,远程调用还能成功吗

Nacos宕机后,短期内已有缓存的服务调用可继续成功,但首次调用或长时间宕机将导致失败。
在这里插入图片描述

Nacos配置中心的数据集和application.properties有相同的配置项,哪个生效

优先级 配置来源(外部优先)
⭐ 最高 命令行参数(--server.port=8081
JVM 系统属性(-Dserver.port=8081
Nacos 配置中心(远程配置),import多个先导入优先
本地 application-{profile}.properties
本地 application.properties
⬇️ 默认 Spring Boot 默认配置

Nacos

在这里插入图片描述

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐