Skip to content

面试速答(先看这里)

**一句话结论:**有可能你看到的很多内存,比如用free命令,是机器内存,而不是JVM内存。

60秒标准回答:

好问题。下次我也问下哈哈哈哈

有以下几个思路供大家参考

1、你看到的可能不是JVM内存

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**这时候需要检查JVM的内存情况,可以用以下方式:
  • **要点2:**有时候,虽然有可能内存挺多的,但是都是碎片,比如老年代采用的标记清除算法的话,就会有很多碎片存在。
  • **要点3:**解决思路是可以考虑改用G1算法,可以避免老年代碎片的发生。
  • **要点4:**FullGC不仅是老年代不足会导致,元空间(老版本的PermGen也会)不足也会导致FullGC
  • **要点5:**这个虽然出现的概率不高,但是我们要知道, 手动调用 System.gc() 会导致 强制 Full GC 。

**记忆锚点:**JVM → Systemgc → FullGC → pid → Systemgc() → 强制 Full GC

易错提醒:

  • 解决思路是可以考虑改用G1算法,可以避免老年代碎片的发生。
  • FullGC不仅是老年代不足会导致,元空间(老版本的PermGen也会)不足也会导致FullGC 如果你的代码中有很多动态类加载的代码,如反射,CGlib等,都会导致大量的类加载,把元空间干满。

追问准备:

  • 围绕「JVM」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「Systemgc」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「FullGC」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

好问题。下次我也问下哈哈哈哈。

有以下几个思路供大家参考:

1、你看到的可能不是JVM内存

有可能你看到的很多内存,比如用free命令,是机器内存,而不是JVM内存。我们需要看JVM内存的情况来判断内存是不是还足够。因为大多数时候我们的JVM内存只是机器内存的1/2 -> 2/3。

这时候需要检查JVM的内存情况,可以用以下方式:

1、jstat -gc <pid> 1000

2、jmap -heap <pid>

3、使用arthas

2、有大量内存碎片

有时候,虽然有可能内存挺多的,但是都是碎片,比如老年代采用的标记清除算法的话,就会有很多碎片存在。

解决思路是可以考虑改用G1算法,可以避免老年代碎片的发生。

3、大对象进入老年代

可能内存还挺多,但是来一个大对象,比剩余的内存还大,那么老年代放不下,就会触发full gc了。

4、元空间不足

FullGC不仅是老年代不足会导致,元空间(老版本的PermGen也会)不足也会导致FullGC

📄 ✅YoungGC和FullGC的触发条件是什么?

打开文档:✅YoungGC和FullGC的触发条件是什么?

如果你的代码中有很多动态类加载的代码,如反射,CGlib等,都会导致大量的类加载,把元空间干满。如这个case:

📄 ✅频繁FullGC问题排查

打开文档:✅频繁FullGC问题排查

5、 过度调用 **System.gc()**

这个虽然出现的概率不高,但是我们要知道, 手动调用 System.gc() 会导致强制 Full GC。而有些第三方库(如 RMI、JDK Management Beans)可能会隐式调用System.gc()。

当上面的问题都排除了,可以考虑下这个方向。