共计 2770 个字符,预计需要花费 7 分钟才能阅读完成。
前言
本系列会零碎的整顿 MySQL,Redis,SSM 框架,算法,计网等面试常问技术栈的面试题,本文次要是整顿分享了 JVM 相干的面试题,MySQL、Spring 之前曾经更新了,须要的同学也能够去看一下,心愿对正在筹备秋招的你们有所帮忙!
JVM 面试题:
- JVM 内存为什么要分成新生代,老年代
- 新生代中为什么要分为 Eden 和 Survivor
- JVM 中一次残缺的 GC 流程是怎么的
- CMS 收集器和 G1 收集器的区别
- JVM 调优
- CPU 飙升如何排查
当然集体整顿的所有面试题都无偿分享,只求大伙一个点赞关注转发三连,这些文档都放在文末了,须要的同学能够自取
1. JVM 内存为什么要分成新生代,老年代?
1.1 JVM 共享内存划分
- 共享内存区 = 长久代 + 堆(jdk1.8 及以上 jvm 废除了长久代)
- 长久代 = 办法区 + 其余
- Java 堆 = 老年代 + 新生代
- 新生代 = Eden + S0 + S1
1.2 为什么分年轻代和新生代
- 新生代:次要寄存新创建的对象,内存大小个别会比拟小,垃圾回收会比拟频繁。
- 老年代(Tenured Gen):次要寄存 JVM 认为生命周期比拟长的对象(通过几次的 Young GC 的垃圾回收后依然存在),或者大对象,垃圾回收也绝对没有那么频繁。
为什么划分老年代和新生代,次要 对象大小不一样,对象生命周期不一样。划分后,提供垃圾回收效率,节俭资源,晋升对象利用率 等等。
2. 新生代为何划分 Eden 和 Survivor?为什么设置两个 Survivor
- 如果没有 Survivor,Eden 区每进行一次 Minor GC,存活的对象就会被送到老年代。老年代很快被填满,触发 Major GC. 老年代的内存空间远大于新生代,进行一次 Full GC 耗费的工夫比 Minor GC 长得多, 所以须要分为 Eden 和 Survivor。
- Survivor 的存在意义,就是缩小被送到老年代的对象,进而缩小 Full GC 的产生,Survivor 的预筛选保障,只有经验 16 次 Minor GC 还能在新生代中存活的对象,才会被送到老年代。
- 设置两个 Survivor 区最大的益处就是解决了碎片化,刚刚新建的对象在 Eden 中,经验一次 Minor GC,Eden 中的存活对象就会被挪动到第一块 survivor space S0,Eden 被清空;等 Eden 区再满了,就再触发一次 Minor GC,Eden 和 S0 中的存活对象又会被复制送入第二块 survivor space S1(这个过程十分重要,因为这种复制算法保障了 S1 中来自 S0 和 Eden 两局部的存活对象占用间断的内存空间,防止了碎片化的产生)
3. JVM 中一次残缺的 GC 流程是怎么的
- Java 堆划分为老年代和新生代
- 新生代 划分为 Eden 和两个 Survivor(S0、S1)
- 当 Eden 区的空间满了,Java 虚构机会触发一次 Minor GC,以收集新生代的垃圾,存活下来的对象,则会转移到 Survivor 区。
- 大对象(须要大量间断内存空间的 Java 对象,如那种很长的字符串)间接进入老年态;
- 如果对象在 Eden 出世,并通过第一次 Minor GC 后依然存活,并且被 Survivor 包容的话,年龄设为 1,每熬过一次 Minor GC,年龄 +1,若年龄超过肯定限度(15),则被降职到老年态。即长期存活的对象进入老年态。
- 老年代满了而无奈包容更多的对象,Minor GC 之后通常就会进行 Full GC,Full GC 清理整个内存堆 – 包含年老代和年轻代。
- Major GC 产生在老年代的 GC,清理老年区,常常会随同至多一次 Minor GC,比 Minor GC 慢 10 倍以上。
4. CMS 收集器和 G1 收集器的区别
- CMS 收集器是老年代的收集器,个别配合新生代的 Serial 和 ParNew 收集器一起应用;G1 收集器收集范畴是老年代和新生代,不须要联合其余收集器应用;
- CMS 收集器是一种以获取 最短回收进展工夫 为指标的收集器,G1 收集器 可预测垃圾回收的进展工夫。
- CMS 收集器是应用“标记 - 革除”算法进行的垃圾回收,容易产生内存碎片;而 G1 收集器应用的是“标记 - 整顿”算法,进行了空间整合,升高了内存空间碎片。
- CMS 和 G1 的回收过程不一样,垃圾回收的过程不一样。CMS 是 初始标记、并发标记、从新标记、并发清理;G1 是初始标记、并发标记、最终标记、筛选回收。
5. JVM 调优
JVM 调优其实就是通过调节 JVM 参数,即对垃圾收集器和内存调配的调优,以达到更高的吞吐和性能。JVM 调优次要调节以下参数
堆栈内存相干
- -Xms 设置初始堆的大小
- -Xmx 设置最大堆的大小
- -Xmn 设置年老代大小,相当于同时配置 -XX:NewSize 和 -XX:MaxNewSize 为一样的值
- -Xss 每个线程的堆栈大小
- -XX:NewSize 设置年老代大小(for 1.3/1.4)
- -XX:MaxNewSize 年老代最大值(for 1.3/1.4)
- -XX:NewRatio 年老代与年轻代的比值(除去长久代)
- -XX:SurvivorRatio Eden 区与 Survivor 区的的比值
- -XX:PretenureSizeThreshold 当创立的对象超过指定大小时,间接把对象调配在老年代。
- -XX:MaxTenuringThreshold 设定对象在 Survivor 复制的最大年龄阈值,超过阈值转移到老年代
垃圾收集器相干
- -XX:+UseParallelGC:抉择垃圾收集器为并行收集器。
- -XX:ParallelGCThreads=20:配置并行收集器的线程数
- -XX:+UseConcMarkSweepGC:设置年轻代为并发收集。
- -XX:CMSFullGCsBeforeCompaction=5 因为并发收集器不对内存空间进行压缩、整顿,所以运行一段时间当前会产生“碎片”,使得运行效率升高。此值设置运行 5 次 GC 当前对内存空间进行压缩、整顿。
- -XX:+UseCMSCompactAtFullCollection:关上对年轻代的压缩。可能会影响性能,然而能够打消碎片
辅助信息相干
- -XX:+PrintGCDetails 打印 GC 详细信息
- -XX:+HeapDumpOnOutOfMemoryError 让 JVM 在产生内存溢出的时候主动生成内存快照, 排查问题用
- -XX:+DisableExplicitGC 禁止零碎 System.gc(),避免手动误触发 FGC 造成问题.
- -XX:+PrintTLAB 查看 TLAB 空间的应用状况
6. CPU 飙升如何排查
- 输出 jps,取得过程号。
- top -Hp pid 获取本过程中所有线程的 CPU 耗时性能
- printf %x cpu 最高的线程(即转为 16 进制)
- jstack 命令查看以后 java 过程的堆栈状态 | grep 那个 16 进制
- 或者 jstack -l > /tmp/output.txt 把堆栈信息打到一个 txt 文件。
材料支付
本文就先写到这里,面试中常问的一些题目我都有整顿的,前面会继续更新,须要 PDF 的好兄弟能够点赞本文 + 关注后【点击此处】即可支付
正文完