您的位置:首页 > 职场人生

高频面试点-JVM+GC解析

2019-07-15 11:37 148 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/WM_CARA/article/details/95505237

目录

基础

问题1:JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots?

问题2:你说你做过JVM调优和参数配置,请问如何盘点查看JVM系统默认值

问题3:你平时使用过的JVM常用基本配置参数有哪些

问题4:强引用、软引用、弱引用、虚引用分别是什么?

 问题5:请谈谈你对OOM的认识?

问题6:GC垃圾回收算法和垃圾收集器的关系?分别是什么请你谈谈?

问题7:怎么查看服务器默认的垃圾收集器是哪个?生产上如何配置垃圾收集器?谈谈你对垃圾收集器的理解?

问题8:G1垃圾收集器

问题9:生产服务器变慢,诊断思路和性能评估? 

问题10:加入生产环境出现CPU占用过高,请谈谈你的分析思路和定位?

问题11:对于JDK自带的JVM监控和性能分析工具用过哪些?一般你是怎么使用的?

基础

四种垃圾回收算法

  1. 复制
  2. 标记-清除
  3. 标记-整理
  4. 分代收集

问题1:JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots?

什么是垃圾:内存中已经不再被使用到的空间就是垃圾。

判断是否是垃圾的方法:

  • 引用计数器

 缺点:较难处理循环引用。

  • 可达性分析

 GC Roots包含哪些

问题2:你说你做过JVM调优和参数配置,请问如何盘点查看JVM系统默认值

  • JVM的参数类型

标配参数

X参数

XX参数(重点)(两种)

Boolean类型

Case:PrintGCDetails(是否打印垃圾回收详情)

修改前:

修改:

 

修改后:

 

KV设值类型

公式:-XX:属性key=属性值value

注意:-Xms相当于-XX:InitialHeapSize。-Xmx等价于MaxHeapSize

  • 查看JVM参数方法一:

java-bin中的jps和jinfo命令可以查看

jps -l:查看当前运行java程序的进程号

jinfo:查看当前线程的参数

查看具体的参数:jinfo -flag 参数名称 进程号

参看所有的jvm参数:jinfo -flags 进程号

[code]public class HelloGC {
public static void main(String[] args) throws InterruptedException {
System.out.println("HelloGC");
Thread.sleep(Integer.MAX_VALUE);
}
}

  • 查看JVM参数方法二(查看JVM的默认值):

java -XX:+PrintFlagsInitial(查看初始参数)

java -XX:+PrintFlagsInitial(查看修改后的参数)

冒号代表参数被修改过 。

java -XX:+PrintFlagsFinal -XX128K T(在运行java程序的时候打印出参数)

 java -XX:+PrintCommandLineFlags(打印命令行参数)(常用参数)

问题3:你平时使用过的JVM常用基本配置参数有哪些

[code]public class 堆内存 {
public static void main(String[] args) {
long totalMemory = Runtime.getRuntime().totalMemory();
long maxMemory = Runtime.getRuntime().maxMemory();
System.out.println("TOTAL_MEMORY(-Xms="+totalMemory+"(字节)"+totalMemory/1024/1024+"MB");
System.out.println("MAX_MEMORY(-Xmx="+maxMemory+"(字节)"+maxMemory/1024/1024+"MB");
}
}
[code]TOTAL_MEMORY(-Xms=128974848(字节)123MB
MAX_MEMORY(-Xmx=1883242496(字节)1796MB

-Xms:初始堆内存大小,一般默认为物理内存的1/64

-Xmx:最大堆内存大小,一般默认为物理内存的1/4

常用参数

  • -Xms:初始堆内存大小。等价于-XX:InitialHeapSize
  • -Xmx:最大堆内存大小。等价于-XX:MaxHeapSize
  • -Xss:设置单个线程栈的大小,一般默认512k~1024k。等价于:-XX:ThreadStackSize

 默认初始值为0。当ThreadStackSize=0代表用的是虚拟机的出厂默认值。依赖于平台(操作系统)

  • -Xmn:设置年轻代的大小。(一般使用默认,新生代占堆内存1/3)
  • -XX:MetaspaceSize:设置元空间的大小

默认值: 约20.7M

 

 可以将元空间配置大一些

  • 典型设置案例

  • -XX:+PrintGCDetails: 打印垃圾回收细节

 测试垃圾回收

 

[code]public class HelloGC {
public static void main(String[] args) throws InterruptedException {
System.out.println("HelloGC");
//大小超过10m
byte[] bytes = new byte[50*1024*1024];
}
}

 

[code][GC (Allocation Failure) [PSYoungGen: 1719K->504K(2560K)] 1719K->683K(9728K), 0.0014074 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

GC:Allocation Failure: 分配失败

FC:

 

  • -XX:SurvivorRatio:设置新生代中eden和s0/s1空间的比例

  • -XX:NewRatio:配置年轻代与老年代在堆结构中的占比

  • -XX:MaxTenuringThreshold:设置垃圾最大年龄

MaxTenuringThreshold只能设置为0~15之间

问题4:强引用、软引用、弱引用、虚引用分别是什么?

整体架构

  • 强引用(默认支持模式)

  • 软引用

使用SoftReference来实现。

  • 弱引用

使用WeakReference来实现

 软引用和弱引用的使用场景?

 问题:你知道软引用的话,能谈谈WeakHashMap?

 

 

 

  • 虚引用(幽灵引用)

 使用PhantomReference和ReferenceQueue实现

虚引用在进行垃圾回收之前会放入引用队列中,可以完成回收之前在引用队列中做一些后续的工作

 

 

  • 引用队列


  •  GCRoots和四大引用小总结

 问题5:请谈谈你对OOM的认识?

  •  StackOverFlowError:

栈溢出,一般发生在递归调用时(栈空间不足)

[code]public class OOM {

public static void main(String[] args) {
stackOverFlow();
}

public static void stackOverFlow(){
stackOverFlow();
}
}

  •  Java Heap Space

堆溢出(堆内存不够用)

[code]public static void javaHeapSpace(){
String str = "";
while (true){
str += str + new Random(111111111)+new Random(222222222);
str.intern();
}
}

  •  GC overhead limit exceeded

GC使用时间很长但回收效率很低。

  • Direct buffer memory

  NIO程序中经常出现

  • unable to create new native thread

  • Metaspace

 Metaspace初始大小为20M

问题6:GC垃圾回收算法和垃圾收集器的关系?分别是什么请你谈谈?

 

 4种主要的垃圾收集器

  • Serial(串行)

它为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有用户线程。所以不适合服务器环境。

  • Parallel(并行)

多个垃圾收集器并行工作,此时用户线程也是暂停的,适用于科学计算/大数据处理首台处理等弱交互场景。

  • CMS(并发)

用户线程和垃圾收集线程可以同时执行(不一定是并行,可交替执行),不需要停顿用户线程。互联网公司多用它,适用对响应时间有要求的场景。

  • G1

G1垃圾回收器将堆内存分割成不同的区域然后并发对其进行垃圾回收。

问题7:怎么查看服务器默认的垃圾收集器是哪个?生产上如何配置垃圾收集器?谈谈你对垃圾收集器的理解?

怎么查看服务器默认的垃圾收集器?

打印java初始参数:

 默认的垃圾收集器:-XX:UseParallelGC(并行垃圾收集器)

默认的垃圾收集器有哪些?

java的gc回收的主要类型有以下几种

CMS(ConcMarkSweep)(并发标记清除)

7种垃圾收集器(重点)

 

  部分参数预先说明

  •  新生代
  • 串行GC(Serial)/(Serial Copying)

 

 

  • 并行GC(ParNew)

 

  • 并行回收GC(Parallel)/Parallel Scavenge)

 

 

  • 老年代
  • 串行GC(Serial Old)/(Serial MSC)

  • 并行GC(Parallel Old)/(Parallel MSC)

  • 并发标记清除GC(CMS)(重点)

 

4步过程:

  1. 初始标记(CMS initial mark)(会停顿):只是标记以下GC Root是能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。
  2. 并发标记(CMS concurrent mark):进行RC Roots跟踪的过程,和用户线程一起,不需要暂停工作线程。主要标记过程,标记全部对象。
  3. 重新标记(CMS remark)(会停顿):为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有工作线程。由于并发标记时,程序依然运行,因此正式清理前再做修正。
  4. 并发清除 (CMS concurrent sweep):

 优点:并发收集低停顿

缺点:

并发执行,对CPU资源压力大

采用标记清除算法会导致大量碎片 

 如何选择垃圾收集器?

 

问题8:G1垃圾收集器

  • 以前收集器的特点

  •  G1是什么?

 保留了CMS低暂停时间的有点,又能够去除CMS产生内存碎片的缺点。可预测的停顿时间。

 G1的优势

  •  G1的底层原理

Region区域化垃圾收集器,最大好处是化整为零,避免全内存扫描,只需要按照区域来进行扫描即可。

 

 

 

  •  回收步骤

 

 4步过程

  •    常用配置参数(了解)

  •  和CMS相比的优势

问题9:生产服务器变慢,诊断思路和性能评估? 

 

问题10:加入生产环境出现CPU占用过高,请谈谈你的分析思路和定位?

问题11:对于JDK自带的JVM监控和性能分析工具用过哪些?一般你是怎么使用的?

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: