常见的 JVM 面试题分析

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

点击下方关注我然后右上角点击...“设为星标”就能第一时间收到更新推送啦~~~

8 个常见的 JVM 面试题分析。

1、什么时候会触发垃圾回收Minor GC 和 Full GC 的区别

垃圾回收 GC 是由 JVM 根据运行情况自动完成的触发垃圾回收的时机是不确定的当然我们可以通过调用System.gc()方法通知 JVM 进行垃圾回收但是什么时候回收还是由 JVM 决定但是不建议手动调用System.gc()方法。一般以下几种情况会发生垃圾回收

  • 当新生代Eden 区或者 S 区空间不够用时触发 Minor GC

  • 当老年代Old 区空间不够用时触发 Major GC进而可能触发 Full GC

  • 当方法区Metaspace 区空间不够用时触发 Full GC

Minor GC 指的是新生代的 GC也就是 Young GC Major GC 指的是老年代的 GC也就是 Old GCFull GC 等于 Young GC+Old GC+Metaspace GC。

2、什么样的对象是垃圾对象垃圾对象一定会被回收吗

在可达性分析法中不可达的对象是垃圾对象但是垃圾对象不一定就会被回收。

一个对象在可达性分析法中如果判定不可达会被初始标记初始标记之后还需要进行一次筛选分析就是看该对象是否需要执行 finalize() 方法。

筛选分析过程如果对象没有覆盖 finalize()  方法或者 finalize()  方法已经被虚拟机调用过那么定该对象不需要执行 finalize()  方法如果被判定为需要执行 finalize()  方法的对象那么就会被放在一个队列中进行再次标记。

再次标记过程再次标记时如果这个对象在引用链上存在任何一个对象与之关联那么就会被激活否则就会被进行垃圾回收。

3、为什么需要 Survivor 区只有 Eden 区可以吗为什么需要两个 Survivor 区

如果没有 Survivor 区Eden 区每进行一次 Minor GC并且没有年龄限制的话存活的对象就会被送到老年代。这样一来老年代很快就会空间用完触发 Major GC老年代的内存空间远大于新生代进行一次 Full GC消耗的时间比 Minor GC长得多。

频繁的 Full GC 消耗的时间很长会影响应用程序的执行和响应速度一般会想到可以增加老年代空间降低 Full GC 频率或者减少老年代空间降低 Full GC所需时间。

如果对老年代的空间进行增加那么更多存活对象才能填满老年代这样虽然降低了 Full GC 频率但是随着老年代空间加大一旦发生 Full GC执行垃圾清理所需要的时间更长。如果减少老年代空间虽然 Full GC 所需时间减少了但是老年代很快被存活对象填满从而 Full GC 的频率增加了。

所以 Survivor 区存在的意义就是发生 Minor GC 时把 Eden 区存活的对象放入 Survivor 区这样可以减少被送到老年代的对象进而减少 Full GC 的发生Survivor 区设置的年龄阈值默认 15也就是说只有经历 16 次 Minor GC 还能在新生代中存活的对象才会被送到老年代从而大大减少了  Full GC 的触发垃圾回收要尽量减少垃圾回收的频率。

两个 Survivor 区最大的好处就是解决了 Young 区空间碎片化的问题。假设现在只有一个 Survivor 区新建的对象在 Eden 区中一旦 Eden 区满了触发一次 Minor GCEden 区中的存活对象就会被移动到 Survivor 区这样继续循环下去当下一次 Eden 区满了的时候再次触发 Minor GC这时 Survivor 区可能有一些存活对象导致 Survivor 区内存是不连续的也就导致了 Survivor 区内存碎片化的问题。再增加一个 Survivor 区就能保证永远有一个 Survivor 区是空的另一个非空的 Survivor 区无碎片。

4、如果 Full GC 频繁怎么办

Full GC 频繁说明老年代涌入了大量对象这个时候就应该检查下 JVM 的参数配置默认 Old:Young=2:1很有可能是新生代设置的太小了导致很多应该在 Minor GC 阶段就清理的对象留到了老年代想办法减少 Full GC 的次数可以适当增加 Young 区的大小来解决。

新生代可以分为 Eden 区、S0 区、S1 区正常的对象分配都是在 Eden 区完成的如果 Eden 区空间不够了会触发一次 Minor GC存活的对象放在 S0 或 S1 中。每执行一次 Minor GC存活的对象会不断地从 S0 迁到 S1再从 S1 迁到S0这个过程经过几次之后当对象年龄为 15 时如果对象还是存活的就会把新生代的对象放入老年代中年龄默认是 15 岁可以通过参数 -XX:MaxTenuringThreshold 来设置。如果新生代大小设置的太小就会导致非常频繁的 Minor GC S0 和 S1 来回切换的速度加快导致本身应该在 Minor GC 就清理出去的对象跑到了老年代从而导致 Full GC 的次数频繁执行。

5、只有 Full GC 才会触发 STW stop the world吗

STW stop the world指的是 GC 执行过程中可能会暂停应用程序的执行这个停顿期间会导致所有应用程序的线程都暂停执行没有任何响应, 有点像卡死的感觉这个停顿叫做 STW。

这种现象一般是由 GC 引起的不管是什么 Full GC 还是 Young GC都会有 STW只是暂停时间的长短不一样垃圾收集器的演进过程就是为了更好地缩短这个停顿时间。

6、CMS 与 G1 垃圾收集器的区别

CMS 和 G1 都是并发回收收集器但是 CMS 只用于老年代的回收而 G1 可用于新生代和老年代的回收。

CMS 使用标记-清理算法实现G1 引入了  Region 内存布局方式使用标记-整理算法实现整体减少了垃圾碎片的产生CMS 和 G1 都在追求最短的用户线程停顿时间为目标但是 G1 比 CMS 先进的是可以指定垃圾回收的停顿时间。

7、内存泄漏和内存溢出的区别

内存泄漏memory leak是指程序在申请内存后无法释放已申请的内存空间导致对象无法得到及时的回收持续占用内存空间从而造成内存空间的浪费内存泄漏的堆积最终会导致内存溢出。

内存溢出out of memory内存溢出就是我们常说的 OOM它是指程序在申请内存时没有足够的内存空间可以为其分配就会内存溢出另外内存溢出也有可能是大对象导致的。

8、方法区垃圾回收的内容是什么

方法区主要存储的是类信息那么方法区垃圾回收主要是回收“无用的类”和“无用的常量”。

如何判断“无用的类”

  • 该类所有的实例都已经被回收也就是堆里面不再有该类任何实例对象

  • 加载该类的 ClassLoader 已经被回收

  • 该类对应的 java.lang.Class 对象没有在任何地方被引用也就是无法通过反射访问该类的方法

一个类需要同时满足上面 3 个条件才能算是“无用的类” 也就是说虚拟机可以对其进行垃圾回收。

运行时常量池主要存储的是常量信息那么运行时常量池回收主要是回收“无用的常量”。

如何判断“无用的常量”

  • 假如在常量池中存在字符串常量"helloWorld" 如果当前没有任何 String 对象引用该字符串常量的话就说明常量"helloWorld"就是“无用的常量”也就是说虚拟机可以对其进行垃圾回收"helloWorld"就会被虚拟机清理出常量池。

JVM 十三个应知应会知识点全部结束

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6