jvm中常见的面试题

一、Full GC 次数过多

特征:

  • 线上多个线程的 CPU 都超过了 100%,通过 jstack 命令可以看到这些线程主要是垃圾回收线程
  • 通过 jstat 命令监控 GC 情况,可以看到 Full GC 次数非常多,并且次数在不断增加。

解决方案:

 1、top命令查看系统 CPU 的占用情况 ,比如进程为id=9的进程cpu消耗高

 2、通过 top -Hp 9 命令找到进程中消耗高的线程(H 代表查看线程视图,p 用来指定具体的进程 )

 3、将十进制的线程 ID(17706)转换成十六进制(452a)

printf "%x\n" 17706
452a 

4、有了十六进制的线程 ID 以后,就可以通过 jstack 命令来精确定位导致 CPU 飙高的代码了。 

jstack 9 | grep -A 20 452a 
"main" #1 prio=5 os_prio=0 tid=0x00007f8718009800 nid=0xb runnable [0x00007f871fe41000]
   java.lang.Thread.State: RUNNABLE
	at com.aibaobei.chapter2.eg2.UserDemo.main(UserDemo.java:9)

"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable

这里的 VM Thread 一行的最后显示 nid=0xa,这里 nid 的意思就是操作系统线程 id 的意思。而 VM Thread 指的就是垃圾回收的线程。这里我们基本上可以确定,当前系统缓慢的原因主要是垃圾回收过于频繁,导致 GC 停顿时间较长

  • jstack命令用于生成虚拟机当前时刻的线程快照
  • jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数] ,我们一般使用 -gcutil 查看gc情况 :
  • jstat -gcutil 9 1000 10

5、通过:jstat -gcutil 9 1000 10(每隔1秒执行1次命令,共执行10次)

 6、可以看到,这里 FGC 指的是 Full GC 数量,这里高达 6793,而且还在不断增长。从而进一步证实了是由于内存溢出导致的系统缓慢。那么这里确认了内存溢出,但是如何查看你是哪些对象导致的内存溢出呢,这个可以 dump 出内存日志,然后通过 eclipse 的 mat 工具进行查看

  • 代码中一次获取了大量的对象,导致内存溢出,此时可以通过 eclipse 的 mat 工具查看内存中有哪些对象比较多;
  • 内存占用不高,但是 Full GC 次数还是比较多,此时可能是显示的 System.gc() 调用导致 GC 次数过多,这可以通过添加 -XX:+DisableExplicitGC 来禁用 JVM 对显示 GC 的响应。

二、CPU飙高系统反应慢怎么排查?

CPU 过高可能是系统频繁的进行 Full GC,导致系统缓慢,也可能遇到比较耗时的计算,导致 CPU 过高的情况。首先我们通过 top 命令查看当前 CPU 消耗过高的进程是哪个,从而得到进程 id;然后通过 top -Hp <pid> 来查看该进程中有哪些线程 CPU 过高,一般超过 80% 就是比较高的,80% 左右是合理情况。这样我们就能得到 CPU 消耗比较高的线程 id。接着通过该线程id的十六进制表示在 jstack 日志中查看当前线程具体的堆栈信息。

       在这里我们就可以区分导致 CPU 过高的原因具体是 Full GC 次数过多还是代码中有比较耗时的计算了。如果是 Full GC 次数过多,那么通过 jstack 得到的线程信息会是类似于 VM Thread 之类的线程,而如果是代码中有比较耗时的计算,那么我们得到的就是一个线程的具体堆栈信息。

2、JVM如何判断一个对象可以被回收

在JVM里面,要判断一个对象是否可以被回收,最重要的是判断这个对象是否还在被使用,只有没被使用的对象才能回收。

  • 引用计数器,每个对象有一个引用计数属性,新增一个引用时计数器加1,引用释放时计数减1,计数为0时候可以回收。引用计数器在处理一些复杂的循环引用或者相互依赖的情况时可能会出现一些不再使用但是又无法回收的内存,造成内存泄露的问题。
  • 可达性分析,它的主要思想是,首先确定一系列肯定不能回收的对象作为GC root,比如虚拟机栈里面的引用对象、本地方法栈引用的对象等,然后以GC ROOT作为起始节点,从这些节点开始向下搜索,去寻找它的直接和间接引用的对象,当遍历完之后如果发现有一些对象不可到达,那么就认为这些对象已经没有用了,需要被回收。

可达性分析是目前主流JVM使用的算法。

三、Minor GC、Full GC、Stop-the-World 

  • Minor GC:对象优先在eden中分配,当eden中没有足够的内存空间时,虚拟机将进行Minor GC
  • Full GC :发生在老年代的gc,当老年代没有足够的空间时候级发生Full GC,发生Full GC ,一般都会有一次Minor GC 
  • Stop-the-World 指GC事件发生过程中,会产生应用程序的停顿,停顿产生时候整个应用线程都会被暂停,没有任何响应,这个停顿被称为Stop-the-World

四、什么是双亲委派模式

双亲委派模型:如果一个类加载器收到类加载的请求,它首先不会自己加载这个类,而是把这个请求委派给父类加载器去完成,每一层类加载器都是如此,这样所有的加载请求都会被传递到顶层的启动类加载器中,只有当父类加载无法完成加载请求时,子类加载器才会尝试加载

好处:1、为了安全性,避免用户编写的类动态替换java的一些核心类 ,同时避免类的重复加载,因为jvm区分不同的类,不仅仅是根据类名,相同class文件被不同的classLoader加载就是不同的两个类

五、介绍CMS垃圾回收器

以牺牲吞吐量为代价来获得最短回收停顿事件的垃圾回收器,使用标记-清除算法,是一种老年代回收器,当gc时候会产生大量的内存碎片,当剩余内存不能满足程序运行要求的时候,系统会出现Concurrent Mode Failure ,临时cms采用serial old 回收器进行垃圾清理

六、简述分代垃圾回收器是怎么工作的?

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。

新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下:

  • 把 Eden + From Survivor 存活的对象放入 To Survivor 区;
  • 清空 Eden 和 From Survivor 分区;
  • From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。

每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。

老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的执行算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程。 

七、说一下类加载的执行过程

  • 1、加载:根据查找路径找到对应的class文件后导入
  • 2、检查:   检查加载的class文件的正确性
  • 3、准备:给类中的静态变量分配内存空间
  • 4、解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用理解为一个标识,而直接引用指向内存中的地址
  • 5、初始化:对静态变量和静态代码执行初始化的工作

八、JVM 常用调优参数

  1. -Xms1024m 初始堆大小 
  2. -Xmx1024m 最大堆大小  一般将 Xms 和 Xmx 设置为相同大小,防止堆扩展,影响性能。
  3. -XX:NewRatio=4:设置年轻的和老年代的内存比列为1:4
  4. -XX:SurvivorRatio=8:设置新生代Eden和Survivor比列是8:2

九、说说jvm有哪些垃圾回收算法

  • 1、标记-清除算法
  • 2、标记-整理:标记无用的对象,让所有存活的对象都向一段移动,然后直接清除掉边界以外的内存
  • 3、复制算法:将内存容量分成大小相等的两块,每次只使用其中一块,当一块用完时,将还存活的对象复制到另一块去,然后把之前使用满的那块空间一次性清理掉,如此反复。
  • 4、分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代基本采用的标记整理算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值