(1)
OOM(java.lang.OutOfMemoryError:Java heap spacess)一般是由堆引起的问题,需要使用Jvm分析工具(如Eclipse Memory Analyzer)来查看是内存溢出还是内存泄漏
如果是内存泄漏,则利用工具查看GC Roots的引用链是否可达。如果是内存溢出,则通过修改Jvm参数(-Xmx与-Xms)的设置是否适当。
SOF(StackOverflowError)一般是栈引起的问题。如果线程请求的栈深度大于虚拟机所允许的最大深度,就会引起该问题
(3)
如何判断对象是否存活
第一个方法是引用计数算法,如果给定一个循环,计数标志改变,则为存活(但如果两个对象间互相引用的话,则不可以用这个方法)
第二个方法是可达性分析算法,GC Roots作为起点,如果可以与对象连接,则为存活。
如果不能连接,且已经被finalize()方法所调用过,那么判定不存活
(4)
JVM最核心的内容有三个,一是内存区域的分布以及各自的特点,一个是垃圾回收机制,还有一个是类加载的过程
(5)
垃圾回收收集器的分析
Serial收集器:单线程有优势
ParNew收集器:多线程有优势
CMS收集器:获取最短回收停顿时间的优势,缺点是产生大量空间碎片(采用标记-整理算法)、并发阶段会降低吞吐量,总结来说是以
资源换取速度
G1收集器:停顿时间少,不会产生空间碎片,采用的是复制回收算法
(6)
并发和并行的概念
并行:指多条垃圾回收线程并行工作,但用户仍然处于等待状态
并发:指用户线程和垃圾回收线程同时进行,有可能用户线程工作在CPU1,另一个工作在CPU2
(7)
class类加载过程:加载,验证(包括4个验证,文件格式验证,元数据验证,字节码验证,符号引用验证),准备(包括所有变量和数据类型都是以零值的形式进行存放,还不存在赋值),解析,初始化
(8)
如果一个类被同一个虚拟机运行,但是不是同一个类加载器加载,那么输出的结果也会不一样
(9)
类加载器的双亲委派模型:双亲指的是除了启动类加载器没有父类,其他类加载器必须有父类,而这种父子
关系一般不是以继承的关系来实现的,而是以组合的方式来实现。委派指的是大多数的Java应用程序都是由系统提供的这三种类加载器加载的,当然还有一些自定义加载类(顺序是从上到下开始加载)
启动类加载器(一般加载Java_home/lib下的类)
扩展类加载器(一般加载Java_home/lib/ext下的类)
应用程序类加载器(一般加载classPath下的类)
自定义类加载器
如果一个类加载器收到了类加载的请求,它首先不会自己加载,而是传递给父类加载器加载,如果父类加载不了,则调用最上层的启动类加载器去加载,
如果都加载不了,才会子类加载器去加载,这就保证了在各种类加载器的情况下,最后加载的也是同一个类
(10)
Java -version 可以查看混合模式
(11)
处理堆栈溢出的方法:
首先使用jps -l看看启动了哪些类
然后使用jmap -dump:format=b,file=heap.hprof +jps -l分析出来的端口号
然后使用eclipse内存分析工具Mat打开导出的文件即可
(12)
借助工具是因为无法从控制台直接查看错误信息
(13)
排查CPU突然飙升(会导致网站无法访问)的方法:
使用top查看cpu的使用情况
使用jstack +cpu使用率最高的Pid > 导出的文件名称
top -p +cpu使用率最高的Pid -H这个指令来把CPU使用前几名的细节展示出来
先将前几名的细节的pid转为16进制的,然后对应查询导出的文件,找到报错信息
(14)
优化GC的步骤:
导出分析报告
使用https://gceasy.io/查看分析情况
自定义调整GC的参数
(15)
评论垃圾收集器的两大指标:
吞吐量和停顿时间