java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > JVM面试题

每日六道java新手入门面试题,通往自由的道路--JVM

作者:太子爷哪吒

这篇文章主要为大家分享了最有价值的6道JVM面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,对hashCode方法的设计、垃圾收集的堆和代进行剖析,感兴趣的小伙伴们可以参考一下

1. JVM是如何判断对象是否可回收

垃圾收集器在做垃圾回收的时候,首先需要判断一个对象是存活状态还是死亡状态,死亡的对象将会被标识为垃圾数据并等待收集器进行清除。

而判断一个对象是否为可回收状态的常用算法有两个:引用计数器法和可达性分析算法。

在 Java 中,引用和对象是有关联的,通过引用计数来判断一个对象是否可以回收。它在创建对象时关联一个与之相对应的计数器,当此对象被使用时加 1,相反销毁时 -1。当此计数器为 0 时,则表示此对象未使用,可以被垃圾收集器回收。其优点是垃圾回收比较及时,实时性比较高,只要对象计数器为 0,则可以直接进行回收操作;而缺点是无法解决循环引用的问题。

主要是从GC Root的对象为起点出发,然后开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Root之间没有任何引用链的时候,代表这个对象不可以用,判断为垃圾,就会被GC回收。

在 java 中可以作为 GC Roots 的对象有以下几种:

2. 你知道有什么垃圾回收的常见算法吗?

标记清除法:

分为标记–清除两个阶段,首先先标记出所有需要回收的对象,然后在标记完成后统一清除回收所有被标记的对象。

它可能产生的问题呢标记清除后,产生一些大量不连续的内存碎片,导致可能以后后续的大内存找不到足够的连续内存再导致提前又发生一次垃圾收集

标记整理法:

基本步骤和标记清除类似,但是多了一步整理的步骤,让所有村后的对象都向一端移动,然后清除掉不需要的内存。

它解决了内存碎片的问题,但是需要频繁的移动存活的对象,效率就比较低了。

复制算法:

将可用的内存分为一半,每次只使用一个区域。将需要存活的对象复制到另一个对象中去。

这种方法也是可以解决了内存碎片问题,但是内存对半分了,而且对象存活率高的对象需要频繁复制。

基于前面的算法的话,JVM采用一个分代算法的形式:

对于JVM的堆来说分为了新生代和老年代两个区域,而新生代也还分了eden区和两个幸存区,他们比例是8:1:1,

对于新生代来说采用了复制算法,因为对于新生代来说每次垃圾回收的存活的对象是比较少的,所以采用复制算法较好,而老年代的话,则采用了标记整理法。

3. 你知道有什么垃圾收集器吗?

常见的垃圾收集器有:其中用于回收新生代的收集器有Serial、PraNew、Parallel Scavenge,而回收老年代的收集器有Serial Old、Parallel Old、CMS,最后还有一个可以用于回收整个Java堆的G1收集器。

作用于新生代的:

特点是简单和高效,并且本身的运行对内存要求不高,因此它在客户端模式下使用的比较多。

作用于老年代的:

作用于整个Java堆包括新生代和老年代的。

4. 那你知道什么时候才会触发Full GC

1.在老年代空间不足的时候:

老年代空间只有在新生代对象发生minor Gc转入或者是直接创建为大对象、大数组时出现空间不足的现象,当JVM执行Full GC后空间仍然不足,则抛出如下错误:java.lang.OutOfMemoryError: Java heap space。

解决措施:尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。

2.在我们程序中直接调用了System.gc, 也会直接出发Full GC。

3.在永久代空间满

永久代中存放的为一些class的信息等,当系统中要加载的类、反射的类和调用的方法较多时,永久代空间可能会被占满,在未配置的时候采用这CMS垃圾收集器的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:java.lang.OutOfMemoryError: PermGen space。

解决措施:可采用的方法为增大永久代空间或转为使用CMS GC。

4.在CMS垃圾收集器出现promotion failed(晋升失败)和concurrent mode failure(并发模式故障)

对于如果我们采用CMS垃圾收集器进行老年代GC的程序而言,我们就需要主要在GC日志中是否有晋升失败和并发模式故障两种状况,当这两种状况出现时可能会触发Full GC:

晋升失败(promotion failed) 是在新生代进行Minor GC时,幸存区中放不下、而对象只能放入老年代,而此时老年代也放不下造成的。

concurrent mode failure是CMS转悠的错误,即并发清楚线程和工作线程同时工作,清理出来老年代的空间不足以存放由新生代晋升到老年代的对象。

解决措施:减少年轻代大小,避免放入老年代时需要分配大的空间,同时调整触发Full GC时的比率以及将触发CMS GC的阀值适当增大

5. JVM中四种引用你有了解过吗?

在 Java 中最常见的就是强引用, 把一个对象赋给一个引用变量,这个引用变量就是一个强引用。即在我们写类似这样User user = new User(),我们new出来的user对象就是一个强引用了!

当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。

软引用需要用 SoftReference 类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。

弱引用需要用 WeakReference 类来实现,它比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,总会回收该对象占用的内存。

6. 说说你知道的几种主要的JVM参数

1.堆设置

2.收集器设置

3.并行收集器设置

4.并发收集器设置

5.JVM 调优的参数

总结

本篇文章就到这里了,如果这篇文章对你也有所帮助,希望您可以多多关注脚本之家的更多内容!

您可能感兴趣的文章:
阅读全文