【校招VIP】Java垃圾回收机制面试题

08月04日 收藏 0 评论 0 java开发

【校招VIP】Java垃圾回收机制面试题

转载声明:原文链接:https://blog.csdn.net/wangyifeng9709/article/details/125916307

一、判断对象是否为垃圾的算法
对象被判定为垃圾的标准:没有被其他对象引用。
1. 引用计数算法:通过判断对象的引用数量来决定对象是否可以被回收;每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1。优点︰执行效率高,程序执行受影响较小;缺点∶无法检测出循环引用的情况,导致内存泄露。
2. 可达性分析算法:通过判断对象的引用链是否可达来决定对象是否可以被回收。可以作为GC Root的对象①虚拟机栈中引用的对象(栈帧中的本地变量表)②方法区中的常量引用的对象③方法区中的类静态属性引用的对象④本地方法栈中JNI ( Native方法)的引用对象⑤活跃线程的引用对象。

二、 谈谈你了解的垃圾回收算法
标记-清除算法(Mark and Sweep):
标记∶从根集合进行扫描,对存活的对象进行标记;清除∶对堆内存从头到尾进行线性遍历,回收不可达对象内存。缺点:碎片化。

复制算法:分为对象面和空闲面,对象在对象面上创建,存活的对象被从对象面复制到空闲面,然后将对象面的所有对象内存清除。优点:解决碎片化问题,顺序分配内存,适用于对象存活率低的场景。

标志-整理算法:是在标记-清除算法的基础上,增加了整理的步骤。标记︰从根集合进行扫描,对存活的对象进行标记;整理∶移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。

分代收集算法:

Minor GC:用于年轻代(生命周期短);Full GC:用于年轻代+老年代;Major GC:有的地方等同于Full GC,有的地方单单指老年代的GC。

对象如何变为老年代?
经历一定Minor次数依然存活的对象;Survivor区域放不下的对象;新生成的大对象。
常见的性能调优参数:①SurvivorRatio:Eden和Survivor的比值,默认8:1;②NewRatio:老年代和年轻代的内存大小比例;③MaxTenuringThreshold:对象从年轻代晋升到老年代经过的GC次数的最大阈值。

触发Full GC的条件
1.老年代空间不足 
2.永久代空间不足:针对JDK8以前的版本
3.调用System.gc()调用了程序来决定要不要回收(回答这三条基本足够)
4. 使用远程方式管理的JDK应用,每小时执行1次Full Gc
5. CMS GC时出现promotion failed, concurrent mode failure 
6. Minor GC晋升到老年代的平均大小大于老年代的剩余空间调用

三、 常见的垃圾收集器
Stop-the-World:发生时,除了GC所在的线程,其他线程都处于停顿状态
Safepoint:安全点,到达安全点停顿下来,一般在方法调用、循环跳转、异常跳转等地方。
JAVA的运行模式有两种,Server与Client 可以通过java -version 来获取。

垃圾收集器图-连线表示可以并存
Serial收集器:单线程收集,进行垃圾收集时,必须暂停所有工作线程简单高效,Client模式下默认的年轻代收集器。
ParNew收集器:多线程,其他和Serial一样,单核效率不如Serial。
Parallel Scavenge收集器:吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),更关注系统的吞吐量。在多核下执行才有优势,Server模式下默认的年轻代收集器。
老年代:
Serial Old收集器:单线程收集,进行垃圾收集时,必须暂停所有工作线程;简单高效,Client模式下默认的老年代收集器;采用标记-整理算法。
Parallel Old收集器:多线程,吞吐量优先。
CMS收集器:标记-清除算法,会带来内存空间碎片化的问题。①初始标记: stop-the-world②并发标记∶并发追溯标记,程序不会停顿③并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象⑤重新标记︰暂停虚拟机,扫描CMS堆中的剩余对象⑥并发清理∶清理垃圾对象,程序不会停顿。
Garbage First:并行和并发;分代收集;标记-整理算法,空间整合;可预测停顿;年轻代和老年代不再物理隔离

四、Object的finalize()方法的作用是否与C++的析构函数作用相同
finalize方法是在垃圾回收时,用于确认该对象是否确认被回收的一个标记过程。确认一个对象真正被回收需要经历两次标记过程:可达性分析没有引用,这是第一次标记,放入F-Queue队列中;finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记。finalize方法不是一定会执行,对象可以在finalize方法中获得自救,避免自己被垃圾回收,同样自救也只能一次。
不相同,析构函数调用确定,而finalize()方法是不确定的。

五、 Java中的强引用,软引用,弱引用,虚引用有什么用
强引用(Strong Reference):
Object obj =new Object();
抛出OutOfMemoryError终止程序也不会回收具有强引用的对象;通过将对象设置为null来弱化引用,使其被回收。

软引用(Soft Reference):
String str =new String("ABC");//强引用
SoftReference softRef =new SoftReference(str);
对象处在有用但是非必须的状态,只有当内存空间不足时,GC才会回收该对象的内存,可以实现高速缓存。

弱引用(Weak Reference ):
String str =new String("ABC");//强引用
WeakReference softRef =new WeakReference(str);
非必须的对象,比软引用更弱一些;GC时会被回收;回收的概率也不大,因为GC线程优先级比较低;适用于引用偶尔被使用且不影响垃圾收集的对象。

虚引用(PhantomReference ):
String str =new String("ABC");//强引用
ReferenceQueue queue =new ReferenceQueue<>();
PhantomReference ref =new PhantomReference<>(str,queue);

不会决定对象的生命周期;任何时候都可能被垃圾收集器回收;跟踪对象被垃圾收集器回收的活动,起哨兵作用;必须和引用队列ReferenceQueue联合使用.

C 0条回复 评论

帖子还没人回复快来抢沙发