目录
基础
问题1:JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots?
问题2:你说你做过JVM调优和参数配置,请问如何盘点查看JVM系统默认值
问题3:你平时使用过的JVM常用基本配置参数有哪些
问题4:强引用、软引用、弱引用、虚引用分别是什么?
问题5:请谈谈你对OOM的认识?
问题6:GC垃圾回收算法和垃圾收集器的关系?分别是什么请你谈谈?
问题7:怎么查看服务器默认的垃圾收集器是哪个?生产上如何配置垃圾收集器?谈谈你对垃圾收集器的理解?
问题8:G1垃圾收集器
问题9:生产服务器变慢,诊断思路和性能评估?
问题10:加入生产环境出现CPU占用过高,请谈谈你的分析思路和定位?
问题11:对于JDK自带的JVM监控和性能分析工具用过哪些?一般你是怎么使用的?
四种垃圾回收算法
什么是垃圾:内存中已经不再被使用到的空间就是垃圾。
判断是否是垃圾的方法:
缺点:较难处理循环引用。
GC Roots包含哪些
标配参数
X参数
XX参数(重点)(两种)
Boolean类型
Case:PrintGCDetails(是否打印垃圾回收详情)
修改前:
修改:
修改后:
KV设值类型
公式:-XX:属性key=属性值value
注意:-Xms相当于-XX:InitialHeapSize。-Xmx等价于MaxHeapSize
java-bin中的jps和jinfo命令可以查看
jps -l:查看当前运行java程序的进程号
jinfo:查看当前线程的参数
查看具体的参数:jinfo -flag 参数名称 进程号
参看所有的jvm参数:jinfo -flags 进程号
public class HelloGC {
public static void main(String[] args) throws InterruptedException {
System.out.println("HelloGC");
Thread.sleep(Integer.MAX_VALUE);
}
}
java -XX:+PrintFlagsInitial(查看初始参数)
java -XX:+PrintFlagsInitial(查看修改后的参数)
冒号代表参数被修改过 。
java -XX:+PrintFlagsFinal -XX128K T(在运行java程序的时候打印出参数)
java -XX:+PrintCommandLineFlags(打印命令行参数)(常用参数)
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");
}
}
TOTAL_MEMORY(-Xms=128974848(字节)123MB
MAX_MEMORY(-Xmx=1883242496(字节)1796MB
-Xms:初始堆内存大小,一般默认为物理内存的1/64
-Xmx:最大堆内存大小,一般默认为物理内存的1/4
常用参数
默认初始值为0。当ThreadStackSize=0代表用的是虚拟机的出厂默认值。依赖于平台(操作系统)
默认值: 约20.7M
可以将元空间配置大一些
测试垃圾回收
public class HelloGC {
public static void main(String[] args) throws InterruptedException {
System.out.println("HelloGC");
//大小超过10m
byte[] bytes = new byte[50*1024*1024];
}
}
[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:
MaxTenuringThreshold只能设置为0~15之间
整体架构
使用SoftReference来实现。
使用WeakReference来实现
软引用和弱引用的使用场景?
问题:你知道软引用的话,能谈谈WeakHashMap?
使用PhantomReference和ReferenceQueue实现
虚引用在进行垃圾回收之前会放入引用队列中,可以完成回收之前在引用队列中做一些后续的工作
栈溢出,一般发生在递归调用时(栈空间不足)
public class OOM {
public static void main(String[] args) {
stackOverFlow();
}
public static void stackOverFlow(){
stackOverFlow();
}
}
堆溢出(堆内存不够用)
public static void javaHeapSpace(){
String str = "";
while (true){
str += str + new Random(111111111)+new Random(222222222);
str.intern();
}
}
GC使用时间很长但回收效率很低。
NIO程序中经常出现
Metaspace初始大小为20M
4种主要的垃圾收集器
它为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有用户线程。所以不适合服务器环境。
多个垃圾收集器并行工作,此时用户线程也是暂停的,适用于科学计算/大数据处理首台处理等弱交互场景。
用户线程和垃圾收集线程可以同时执行(不一定是并行,可交替执行),不需要停顿用户线程。互联网公司多用它,适用对响应时间有要求的场景。
G1垃圾回收器将堆内存分割成不同的区域然后并发对其进行垃圾回收。
怎么查看服务器默认的垃圾收集器?
打印java初始参数:
默认的垃圾收集器:-XX:UseParallelGC(并行垃圾收集器)
默认的垃圾收集器有哪些?
java的gc回收的主要类型有以下几种
CMS(ConcMarkSweep)(并发标记清除)
7种垃圾收集器(重点)
部分参数预先说明
4步过程:
优点:并发收集低停顿
缺点:
并发执行,对CPU资源压力大
采用标记清除算法会导致大量碎片
如何选择垃圾收集器?
保留了CMS低暂停时间的有点,又能够去除CMS产生内存碎片的缺点。可预测的停顿时间。
G1的优势
Region区域化垃圾收集器,最大好处是化整为零,避免全内存扫描,只需要按照区域来进行扫描即可。
4步过程