JUC高频面试八股总结个人开源
JVMJVM 物理内存区域的划分[图片]线程私有的有程序计数器记录着当前线程执行到了哪一行字节码指令。万一中途 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 及之前的版本中主要有三个核心的类加载器它们呈层级关系启动类加载器 它是最顶层的。负责加载 JDK 的核心类库即 JAVA_HOME/lib 目录下的类比如 String、System 等。注意点它是由 C 实现的所以我们在 Java 代码里拿不到它的引用会返回 null。扩展类加载器 它负责加载 JDK 的扩展库JAVA_HOME/lib/ext 目录。应用类加载器 这是我们平时接触最多的。它负责加载 Classpath 下的类也就是我们自己写的代码和引入的第三方 jar 包。”双亲委派模型双亲委派是一种类加载规则当一个类加载器收到类加载请求时它不会自己先去尝试加载而是将这个加载请求委派给父类加载器。避免类的重复加载保证核心API的安全为什么要这么设计核心优势绝对安全沙箱机制假设黑客自己写了一个 java.lang.String 类企图破坏系统。因为双亲委派机制这个请求会一路向上交给启动类加载器启动类加载器会直接加载 JDK 原生的 String黑客的自定义类永远无法被加载从而保护了 JVM 底层的安全。避免重复加载如果上级已经加载过这份图纸下级就不会再加载了保证了类的唯一性。追问1父加载器是子加载器的父类吗不是继承关系而是组合关系。 它们在代码层面并没有 extends 关系而是通过一个 parent 成员变量持有父加载器的引用。这是一种包含关系不是类继承双亲委派虽然安全但有时太死板了。在某些场景下必须“以下犯上”Tomcat 容器Tomcat 为了让不同的 Web 应用比如应用A和应用B可以使用不同版本的同名第三方包而不发生冲突它为每个应用创建了独立的自定义类加载器实现了类的隔离什么是 OOM怎么排查内存溢出OOMOut Of Memory是指内存耗尽。常见有堆溢出存放业务对象的堆内存、元空间溢出存放类信息的元空间、栈溢出方法无限递归调用等。我理解排查 OOM 的核心在于‘保留现场’和‘顺藤摸瓜’。生产环境绝对不能裸奔我会在启动参数里强制开启 -XX:HeapDumpOnOutOfMemoryError确保 OOM 发生时能自动保存内存快照。拿到快照后我不会盲目看而是用 MAT 工具重点排查两点一是通过 Dominator Tree 找出内存占用最大的嫌疑对象二是通过 GC Roots 引用链定位到是哪行代码或哪个缓存没有及时释放它。在实际业务中OOM 往往是因为集合类如 HashMap、List只进不出或者 ThreadLocal 用完没 remove 导致的内存泄漏。”[图片][图片][图片][图片]如何判断是不是垃圾[图片]
上一篇/下一篇内容由系统自动关联
返回资讯列表 →