☰
JUC高频面试八股总结个人开源
2026/10/2 12:57:14 网站建设 项目流程

JVM

JVM 物理内存区域的划分
[图片]
线程私有的有
程序计数器:(记录着当前线程执行到了哪一行字节码指令。万一中途 CPU 切走了,下次CPU回来照着地址就能无缝衔接。)
虚拟机栈:每个方法执行都会创建一个栈帧,存储方法参数、方法内局部变量,如果(递归太深)就会发生“栈溢出"(StackOverflowError)
本地方法栈:使Java通过本地方法调用操作系统底层功能。

线程共享的有
堆:保存对象实例
[图片]
方法区:保存类信息、静态变量、常量
方法区(使用本地内存,受jvm内存限制)->jkd1.8后被元空间取代(本地内存,降低了内存溢出的风险)

[图片]

[图片]

垃圾回收:
垃圾:没被引用的对象
[图片]

三种垃圾回收算法
[图片]
JVM 的垃圾回收算法有哪些?新生代和老年代分别用什么?

  • 标准回答:主要有标记-清除、标记-整理、复制算法。新生代常用复制算法(Minor GC),老年代常用标记-整理(Major/Full GC)。
  • 我的理解/加分项:新生代用复制算法是因为大部分对象都是“朝生夕灭”的,复制存活对象的成本很低。老年代对象存活率高,如果用复制算法会导致大量无效复制,所以用标记-整理。现在的 G1 和 ZGC 则是把内存切分成 Region,打破了物理上的新生代/老年代界限,实现了更可控的停顿时间。

分代回收:年轻代,老年代
[图片]
[图片]

垃圾回收器:
CMS 老年代,高响应比优先,采用了标记清除,并发标记和并发清理阶段允许用户线程和垃圾回收线程同时工作,缺点是会产生内存碎片,而且对 CPU 资源比较敏感。
G1 全年代,可设置每次垃圾回收STW的暂停时间(精准计算在 200ms 内能清理哪些格子,确保绝不超时),把堆内存划分为若干个大小相同的区先回收垃圾多的,兼顾吞吐和停顿,更适合大堆和需要可控停顿的场景。
[图片]

JVM调优
[图片]

[图片]

[图片]

类加载机制:

[图片]
[图片]

类加载器的作用就是把编译好的 .class 字节码文件加载到 JVM 内存中。 在 JDK 8 及之前的版本中,主要有三个核心的类加载器,它们呈层级关系:

  1. 启动类加载器: 它是最顶层的。负责加载 JDK 的核心类库(即 JAVA_HOME/lib 目录下的类,比如 String、System 等)。
  • 注意点:它是由 C++ 实现的,所以我们在 Java 代码里拿不到它的引用(会返回 null)。
  1. 扩展类加载器 : 它负责加载 JDK 的扩展库(JAVA_HOME/lib/ext 目录)。
  2. 应用类加载器: 这是我们平时接触最多的。它负责加载 Classpath 下的类,也就是我们自己写的代码和引入的第三方 jar 包。”

双亲委派模型:
双亲委派是一种类加载规则:当一个类加载器收到类加载请求时,它不会自己先去尝试加载,而是将这个加载请求委派给父类加载器。
避免类的重复加载
保证核心API的安全
为什么要这么设计?(核心优势)

  1. 绝对安全(沙箱机制):假设黑客自己写了一个 java.lang.String 类企图破坏系统。因为双亲委派机制,这个请求会一路向上交给启动类加载器,启动类加载器会直接加载 JDK 原生的 String,黑客的自定义类永远无法被加载,从而保护了 JVM 底层的安全。
  2. 避免重复加载:如果上级已经加载过这份图纸,下级就不会再加载了,保证了类的唯一性。
    追问1:父加载器是子加载器的父类吗?
    不是继承关系,而是组合关系。 它们在代码层面并没有 extends 关系,而是通过一个 parent 成员变量持有父加载器的引用。这是一种包含关系,不是类继承

双亲委派虽然安全,但有时太死板了。在某些场景下,必须“以下犯上”:
Tomcat 容器:Tomcat 为了让不同的 Web 应用(比如应用A和应用B)可以使用不同版本的同名第三方包而不发生冲突,它为每个应用创建了独立的自定义类加载器,实现了类的隔离

什么是 OOM?怎么排查内存溢出?
OOM(Out Of Memory)是指内存耗尽。常见有堆溢出(存放业务对象的堆内存)、元空间溢出(存放类信息的元空间)、栈溢出(方法无限递归调用)等。
我理解排查 OOM 的核心在于‘保留现场’和‘顺藤摸瓜’。
生产环境绝对不能裸奔,我会在启动参数里强制开启 -XX:+HeapDumpOnOutOfMemoryError,确保 OOM 发生时能自动保存内存快照。
拿到快照后,我不会盲目看,而是用 MAT 工具重点排查两点:
一是通过 Dominator Tree 找出内存占用最大的嫌疑对象;
二是通过 GC Roots 引用链,定位到是哪行代码或哪个缓存没有及时释放它。在实际业务中,OOM 往往是因为集合类(如 HashMap、List)只进不出,或者 ThreadLocal 用完没 remove 导致的内存泄漏。”

[图片]

[图片]

[图片]

[图片]

如何判断是不是垃圾
[图片]

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询