前言

本系列会零碎的整顿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的好兄弟能够点赞本文+关注后【点击此处】即可支付