Skip to content

JVM 面试题

1. JVM 内存模型是怎样的?

JVM 运行时数据区分为:

  • 线程私有

    • 程序计数器:记录当前线程执行的字节码行号
    • 虚拟机栈:方法调用时创建栈帧,存放局部变量表、操作数栈等
    • 本地方法栈:Native 方法调用
  • 线程共享

    • 堆:存放对象实例,GC 主要管理区域
    • 方法区(元空间):存放类信息、常量、静态变量

2. 堆内存的分代结构?


├── 新生代(1/3)
│   ├── Eden 区(8/10)
│   ├── Survivor 0(1/10)
│   └── Survivor 1(1/10)
└── 老年代(2/3)
  • 对象优先在 Eden 分配
  • 经历 Minor GC 后存活的对象进入 Survivor
  • 每经历一次 GC 年龄 +1,达到 15(默认)进入老年代
  • 大对象直接进入老年代

3. 类加载过程是怎样的?

加载 → 验证 → 准备 → 解析 → 初始化
  • 加载:获取类的二进制字节流,转为方法区数据结构,生成 Class 对象
  • 验证:确保 Class 文件格式正确
  • 准备:为静态变量分配内存并赋默认值
  • 解析:将常量池中的符号引用替换为直接引用
  • 初始化:执行类构造器 <clinit> 方法

4. 什么是双亲委派模型?为什么要这样设计?

双亲委派:类加载器收到加载请求时,先委托父加载器加载,父加载器找不到时才自己加载。

好处

  • 避免类的重复加载
  • 保证核心 API 不被篡改(如 String 类只能由 Bootstrap ClassLoader 加载)

5. 垃圾回收算法有哪些?

算法原理优缺点
标记-清除标记可回收对象,然后清除产生内存碎片
标记-整理标记后让存活对象向一端移动无碎片,耗时长
复制分两块内存,存活对象复制到另一块无碎片,内存利用率低
分代收集新生代用复制,老年代用标记-整理综合性能最优

6. 如何排查 OOM 问题?

  1. 获取 dump 文件:-XX:+HeapDumpOnOutOfMemoryError
  2. 使用 MAT / JProfiler 分析 dump 文件
  3. 查看大对象和 GC Roots 引用链
  4. 定位到具体代码位置进行优化