关于JVM垃圾 *** 器的面试题

1、简述Java垃圾接纳机制

2、GC是什么?为什么要GC

3、垃圾接纳的优点和原理。并思量2种接纳机制

4、垃圾接纳器的基本原理是什么?垃圾接纳器可以马上接纳内存吗?有什么设施自动通知虚拟机举行垃圾接纳?

5、Java 中都有哪些引用类型?

6、怎么判断工具是否可以被接纳?

7、在Java中,工具什么时刻可以被垃圾接纳

8、JVM中的永远代中会发生垃圾接纳吗

9、说一下 JVM 有哪些垃圾接纳算法?

10、说一下 JVM 有哪些垃圾接纳器?

11、详细先容一下 CMS 垃圾接纳器?

12、新生代垃圾接纳器和老年月垃圾接纳器都有哪些?有什么区别?

13、简述分代垃圾接纳器是怎么事情的?

1、简述Java垃圾接纳机制

在java中,程序员是不需要显示的去释放一个工具的内存的,而是由虚拟机自行执行。在JVM中,有一个垃圾接纳线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫面那些没有被任何引用的工具,并将它们添加到要接纳的聚集中,举行接纳。

2、GC是什么?为什么要GC

GC 是垃圾 *** 的意思(Gabage Collection),内存处置是编程职员容易泛起问题的地方,遗忘或者错误的内存

接纳会导致程序或系统的不稳定甚至溃逃,Java 提供的 GC 功效可以自动监测工具是否跨越作用域从而到达自动

接纳内存的目的,Java 语言没有提供释放已分配内存的显示操作方法。

3、垃圾接纳的优点和原理。并思量2种接纳机制

Java语言最显著的特点就是引入了垃圾接纳机制,它使java程序员在编写程序时不再思量内存治理的问题。

由于有这个垃圾接纳机制,java中的工具不再有“作用域”的观点,只有引用的工具才有“作用域”。

垃圾接纳机制有用的防止了内存泄露,可以有用的使用可使用的内存。

垃圾接纳器通常作为一个单独的低级其余线程运行,在不能预知的情况下对内存堆中已经殒命的或很长时间没有用过的工具举行消灭和接纳。

程序员不能实时的对某个工具或所有工具挪用垃圾接纳器举行垃圾接纳。

垃圾接纳有分代复制垃圾接纳、符号垃圾接纳、增量垃圾接纳。

4、垃圾接纳器的基本原理是什么?垃圾接纳器可以马上接纳内存吗?有什么设施自动通知虚拟机举行垃圾接纳?

对于GC来说,当程序员建立工具时,GC就更先监控这个工具的地址、巨细以及使用情况。

通常,GC接纳有向图的方式纪录和治理堆(heap)中的所有工具。通过这种方式确定哪些工具是"可达的",哪些工具是"不能达的"。当GC确定一些工具为"不能达"时,GC就有责任接纳这些内存空间。

可以。程序员可以手动执行System.gc(),通知GC运行,然则Java语言规范并不保证GC一定会执行。

5、Java 中都有哪些引用类型?

  • 强引用:发生 gc 的时刻不会被接纳。

  • 软引用:有用但不是必须的工具,在发生内存溢出之前会被接纳。

  • 弱引用:有用但不是必须的工具,在下一次GC时会被接纳。

  • 虚引用(幽灵引用/幻影引用):无法通过虚引用获得工具,用 PhantomReference 实现虚引用,虚引用的用途是在 gc 时返回一个通知。

6、怎么判断工具是否可以被接纳?

垃圾 *** 器在做垃圾接纳的时刻,首先需要判断的就是哪些内存是需要被接纳的,哪些工具是「存活」的,是不能以被接纳的;哪些工具已经「死掉」了,需要被接纳。

一样平常有两种方法来判断:

  • 引用计数器法:为每个工具建立一个引用计数,有工具引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被接纳。它有一个瑕玷不能解决循环引用的问题;

  • 可达性剖析算法:从 GC Roots 更先向下搜索,搜索所走过的路径称为引用链。当一个工具到 GC Roots 没有任何引用链相连时,则证实此工具是可以被接纳的。

7、在Java中,工具什么时刻可以被垃圾接纳

当工具对当前使用这个工具的应用程序变得不能触及的时刻,这个工具就可以被接纳了。

垃圾接纳不会发生在永远代,若是永远代满了或者是跨越了临界值,会触发完全垃圾接纳(Full GC)。若是你仔细查看垃圾 *** 器的输出信息,就会发现永远代也是被接纳的。这就是为什么准确的永远代巨细对制止Full GC是异常主要的缘故原由。

8、JVM中的永远代中会发生垃圾接纳吗

垃圾接纳不会发生在永远代,若是永远代满了或者是跨越了临界值,会触发完全垃圾接纳(Full GC)。若是你仔细查看垃圾 *** 器的输出信息,就会发现永远代也是被接纳的。这就是为什么准确的永远代巨细对制止Full GC是异常主要的缘故原由。请参考下Java8:从永远代到元数据区

(译者注:Java8中已经移除了永远代,新加了一个叫做元数据区的native内存区)

9、说一下 JVM 有哪些垃圾接纳算法?

  • 符号-消灭算法:符号无用工具,然后举行消灭接纳。瑕玷:效率不高,无法消灭垃圾碎片。

  • 复制算法:凭据容量划分二个巨细相等的内存区域,当一块用完的时刻将在世的工具复制到另一块上,然后再把已使用的内存空间一次清算掉。瑕玷:内存使用率不高,只有原来的一半。

  • 符号-整理算法:符号无用工具,让所有存活的工具都向一端移动,然后直接消灭掉端界限以外的内存。

  • 分代算法:凭据工具存活周期的差别将内存划分为几块,一样平常是新生代和老年月,新生代基本接纳复制算法,老年月接纳符号整理算法。

符号-消灭算法

符号无用工具,然后举行消灭接纳。

符号-消灭算法(Mark-Sweep)是一种常见的基础垃圾 *** 算法,它将垃圾 *** 分为两个阶段:

  • 符号阶段:符号出可以接纳的工具。

  • 消灭阶段:接纳被符号的工具所占用的空间。

符号-消灭算法之所以是基础的,是由于后面讲到的垃圾 *** 算法都是在此算法的基础上举行改善的。

优点:实现简朴,不需要工具举行移动。

瑕玷:符号、消灭历程效率低,发生大量不延续的内存碎片,提高了垃圾接纳的频率。

符号-消灭算法的执行的历程如下图所示

复制算法

为领会决符号-消灭算法的效率不高的问题,发生了复制算法。它把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾 *** 时,遍历当前使用的区域,把存活工具复制到另外一个区域中,最后将当前使用的区域的可接纳的工具举行接纳。

优点:按顺序分配内存即可,实现简朴、运行高效,不用思量内存碎片。

瑕玷:可用的内存巨细缩小为原来的一半,工具存活率高时会频仍举行复制。

复制算法的执行历程如下图所示

符号-整理算法

在新生代中可以使用复制算法,然则在老年月就不能选择复制算法了,由于老年月的工具存活率会较高,这样会有较多的复制操作,导致效率变低。符号-消灭算法可以应用在老年月中,然则它效率不高,在内存接纳后容易发生大量内存碎片。因此就泛起了一种符号-整理算法(Mark-Compact)算法,与符号-整理算法差别的是,在符号可接纳的工具后将所有存活的工具压缩到内存的一端,使他们紧凑的排列在一起,然后对端界限以外的内存举行接纳。接纳后,已用和未用的内存都各自一边。

优点:解决了符号-清算算法存在的内存碎片问题。

瑕玷:仍需要举行局部工具移动,一定程度上降低了效率。

符号-整理算法的执行历程如下图所示

分代 *** 算法

当前商业虚拟机都接纳分代 *** 的垃圾 *** 算法。分代 *** 算法,顾名思义是凭据工具的存活周期将内存划分为几块。一样平常包罗年轻代、老年月 和 永远代,如图所示:

10、说一下 JVM 有哪些垃圾接纳器?

若是说垃圾 *** 算法是内存接纳的方法论,那么垃圾 *** 器就是内存接纳的详细实现。下图展示了7种作用于差别分代的 *** 器,其中用于接纳新生代的 *** 器包罗Serial、PraNew、Parallel Scavenge,接纳老年月的 *** 器包罗Serial Old、Parallel Old、CMS,另有用于接纳整个Java堆的G1 *** 器。差别 *** 器之间的连线示意它们可以搭配使用。

  • Serial *** 器(复制算法): 新生代单线程 *** 器,符号和清算都是单线程,优点是简朴高效;

  • ParNew *** 器 (复制算法): 新生代收并行集器,实际上是Serial *** 器的多线程版本,在多核CPU环境下有着比Serial更好的显示;

  • Parallel Scavenge *** 器 (复制算法): 新生代并行 *** 器,追求高吞吐量,高效行使 CPU。吞吐量 = 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高效率的行使CPU时间,尽快完成程序的运算义务,适合后台应用等对交互响应要求不高的场景;

  • Serial Old *** 器 (符号-整理算法): 老年月单线程 *** 器,Serial *** 器的老年月版本;

  • Parallel Old *** 器 (符号-整理算法): 老年月并行 *** 器,吞吐量优先,Parallel Scavenge *** 器的老年月版本;

  • CMS(Concurrent Mark Sweep) *** 器(符号-消灭算法): 老年月并行 *** 器,以获取最短接纳停留时间为目的的 *** 器,具有高并发、低停留的特点,追求最短GC接纳停留时间。

  • G1(Garbage First) *** 器 (符号-整理算法): Java堆并行 *** 器,G1 *** 器是JDK1.7提供的一个新 *** 器,G1 *** 器基于“符号-整理”算法实现,也就是说不会发生内存碎片。此外,G1 *** 器差别于之前的 *** 器的一个主要特点是:G1接纳的局限是整个Java堆(包罗新生代,老年月),而前六种 *** 器接纳的局限仅限于新生代或老年月。

11、详细先容一下 CMS 垃圾接纳器?

CMS 是英文 Concurrent Mark-Sweep 的简称,是以牺牲吞吐量为价值来获得最短接纳停留时间的垃圾接纳器。对于要求服务器响应速度的应用上,这种垃圾接纳器异常适合。在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾接纳器。

CMS 使用的是符号-消灭的算法实现的,所以在 gc 的时刻回发生大量的内存碎片,当剩余内存不能知足程序运行要求时,系统将会泛起 Concurrent Mode Failure,暂且 CMS 会接纳 Serial Old 接纳器举行垃圾消灭,此时的性能将会被降低。

12、新生代垃圾接纳器和老年月垃圾接纳器都有哪些?有什么区别?

  • 新生代接纳器:Serial、ParNew、Parallel Scavenge

  • 老年月接纳器:Serial Old、Parallel Old、CMS

  • 整堆接纳器:G1

新生代垃圾接纳器一样平常接纳的是复制算法,复制算法的优点是效率高,瑕玷是内存行使率低;老年月接纳器一样平常接纳的是符号-整理的算法举行垃圾接纳。

13、简述分代垃圾接纳器是怎么事情的?

分代接纳器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 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)时,升级为老生代。大工具也会直接进入老生代。

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

最后

迎接关注民众号:程序员追风,领取Java知识点学习头脑导图总结+一线大厂Java面试题总结+一份300页pdf文档的Java焦点知识点总结!