@@ -915,39 +915,41 @@ G1 主要解决了内存碎片过多的问题。
915
915
916
916
### 29.你们线上用的什么垃圾收集器?为什么要用它?
917
917
918
- 怎么说呢,虽然调优说的震天响,但是我们一般都是用默认。管你 Java 怎么升,我用 8,那么 JDK1.8 默认用的是什么呢?
918
+ 我们生产环境中采用了设计比较优秀的 G1 垃圾收集器,因为它不仅能满足低停顿的要求,而且解决了 CMS 的浮动垃圾问题、内存碎片问题。
919
919
920
- 可以使用命令:
920
+ G1 非常适合大内存、多核处理器的环境。
921
+
922
+ > 以上是比较符合面试官预期的回答,但实际上,大多数情况下我们可能还是使用的 JDK 8 默认垃圾收集器。
923
+
924
+ 可以通过以下命令查看当前 JVM 的垃圾收集器:
921
925
922
926
``` java
923
927
java - XX : + PrintCommandLineFlags - version
924
928
```
925
929
926
- 可以看到有这么一行:
930
+ ![ 二哥的 Java 进阶之路:JDK 默认垃圾收集器 ] ( https://cdn.tobebetterjavaer.com/stutymore/jvm-20240613111454.png )
927
931
928
- ``` java
929
- - XX : + UseParallelGC
930
- ```
932
+ ` UseParallelGC ` = ` Parallel Scavenge + Parallel Old ` ,表示新生代用` Parallel Scavenge ` 收集器,老年代使用` Parallel Old ` 收集器。
931
933
932
- ` UseParallelGC ` = ` Parallel Scavenge + Parallel Old ` ,表示的是新生代用的 ` Parallel Scavenge ` 收集器,老年代用的是 ` Parallel Old ` 收集器 。
934
+ 因此你也可以这样回答:我们系统的业务相对复杂,但并发量并不是特别高,所以我们选择了适用于多核处理器、能够并行处理垃圾回收任务,且能提供高吞吐量的 ` Parallel GC ` 。
933
935
934
- 那为什么要用这个呢?默认的呗。
936
+ 但这个说法不讨喜,你也可以回答:
935
937
936
- 当然面试肯定不能这么答 。
938
+ 我们系统采用的是 CMS 收集器,能够最大限度减少应用暂停时间 。
937
939
938
- Parallel Scavenge 的特点是什么 ?
940
+ #### 工作中项目使用的什么垃圾回收算法 ?
939
941
940
- 高吞吐,我们可以回答:因为我们系统是业务相对复杂,但并发并不是非常高,所以希望尽可能的利用处理器资源,出于提高吞吐量的考虑采用 ` Parallel Scavenge + Parallel Old ` 的组合 。
942
+ 我们生产环境中采用了设计比较优秀的 G1 垃圾收集器,G1 采用的是分区式标记-整理算法,将堆划分为多个区域,按需回收,适用于大内存和多核环境,能够同时考虑吞吐量和暂停时间 。
941
943
942
- 当然,这个默认虽然也有说法,但不太讨喜。
944
+ 或者:
943
945
944
- 还可以说:
946
+ 我们系统采用的是 CMS 收集器,CMS 采用的是标记-清除算法,能够并发标记和清除垃圾,减少暂停时间,适用于对延迟敏感的应用。
945
947
946
- 采用 ` Parallel New ` + ` CMS ` 的组合,我们比较关注服务的响应速度,所以采用了 CMS 来降低停顿时间。
948
+ 再或者:
947
949
948
- 或者一步到位:
950
+ 我们系统采用的是 Parallel 收集器,Parallel 采用的是年轻代使用复制算法,老年代使用标记-整理算法,适用于高吞吐量要求的应用。
949
951
950
- 我们线上采用了设计比较优秀的 G1 垃圾收集器,因为它不仅满足我们低停顿的要求,而且解决了 CMS 的浮动垃圾问题、内存碎片问题。
952
+ > 1 . [ Java 面试指南(付费) ] ( https://javabetter.cn/zhishixingqiu/mianshi.html ) 收录的华为 OD 面经同学 3 技术二面面试原题:工作中项目使用的什么垃圾回收算法
951
953
952
954
### 30.垃圾收集器应该如何选择?
953
955
@@ -1310,15 +1312,21 @@ Heap dump file created
1310
1312
> 1 . [ Java 面试指南(付费)] ( https://javabetter.cn/zhishixingqiu/mianshi.html ) 收录的京东同学 10 后端实习一面的原题:什么是内存泄露
1311
1313
> 2 . [ Java 面试指南(付费)] ( https://javabetter.cn/zhishixingqiu/mianshi.html ) 收录的快手面经同学 1 部门主站技术部面试原题:Java 哪些内存区域会发生 OOM?为什么?
1312
1314
1313
- ### 41.有没有处理过内存溢出问题 ?
1315
+ ### 41.有没有处理过 OOM 问题 ?
1314
1316
1315
- 内存溢出(Out of Memory,俗称 OOM)是指当程序请求分配内存时,由于没有足够的内存空间满足其需求,从而触发的错误。
1317
+ OOM,也就是内存溢出,Out of Memory,是指当程序请求分配内存时,由于没有足够的内存空间满足其需求,从而触发的错误。
1318
+
1319
+ 当发生 OOM 时,可以导出堆转储(Heap Dump)文件进行分析。如果 JVM 还在运行,可以使用 jmap 命令手动生成 Heap Dump 文件:
1320
+
1321
+ ``` shell
1322
+ jmap -dump:format=b,file=heap.hprof < pid>
1323
+ ```
1316
1324
1317
- 首先,我会通过异常信息和日志确定 OOM 的类型。Java 的 OOM 错误通常有几种类型,如堆内存溢出、Metaspace 溢出或直接内存溢出。比如,如果日志中显示“java.lang.OutOfMemoryError: Java heap space”,那就说明是堆内存溢出 。
1325
+ 生成 Heap Dump 文件后,可以使用 MAT、JProfiler 等工具进行分析,查看内存中的对象占用情况,找到内存泄漏的原因 。
1318
1326
1319
- 一旦确定了是堆内存溢出,我会使用 JConsole 实时监控 JVM 的内存使用情况,特别是那些占用大量内存的对象和类 。
1327
+ 如果生产环境的内存还有很多空余,可以适当增大堆内存大小,例如 ` -Xmx4g ` 参数 。
1320
1328
1321
- 找到可能的内存泄漏源后,我会回到代码中去,查找和修复具体的问题 。
1329
+ 或者检查代码中是否存在内存泄漏,如未关闭的资源、长生命周期的对象等 。
1322
1330
1323
1331
之后,我会在本地进行压力测试,模拟高负载情况下的内存表现,确保修改有效,且没有引入新的问题。
1324
1332
0 commit comments