一.题目介绍
1.题目来源
实际面试中遇到,形式的话有书面解答也有口述。一般侧重点是JVM的内存模型,GC的判定,GC收集方法,java 中垃圾收集的方法有哪些?
2.题目
1)JVM的内存模型
2)GC的判定
3)java中垃圾收集的方法有哪些?
二.具体解答
1.JVM的内存模型
如图由以下几部分构成:
1)线程私有的数据区,包括程序计数器、虚拟机栈和本地方法栈三个区域
2)线程共享的数据区(Java堆和方法区)
3)本地方法栈(Native Method Stack)
2.GC的判定
1)引用计数法:指的是如果某个地方引用了这个对象就+1,如果失效了就-1,当为0就会回收但是JVM没有用这种方式,因为无法判定相互循环引用(A引用B,B引用A的情况。
2)引用链法: 通过一种GC ROOT 的对象(方法区中静态变量引用的对象等-static 变量)来判断,如果有一条链能够到达GC ROOT 就说明,不能到达GC ROOT就说明可以回收。
3.java中垃圾收集的方法有哪些?
1)标记-清除: 这是垃圾收集算法中最基础的,根据名字就可以知道,它的思想就是标记哪些要被 回收的对象,然后统一回收。这种方法很简单,但是会有两个主要问题:1.效率不 高,标记和清除的效率都很低;
2)会产生大量不连续的内存碎片,导致以后程序在 分配较大的对象时,由于没有充足的连续内存而提前触发一次 GC 动作。 2. 复制算法: 为了解决效率问题,复制算法将可用内存按容量划分为相等的两部分,然后每次只 使用其中的一块,当一块内存用完时,就将还存活的对象复制到第二块内存上,然 后一次性清楚完第一块内存,再将第二块上的对象复制到第一块。但是这种方式, 内存的代价太高,每次基本上都要浪费一般的内存。 于是将该算法进行了改进,内存区域不再是按照 1:1 去划分,而是将内存划分为 8:1:1 三部分,较大那份内存交 Eden 区,其余是两块较小的内存区叫 Survior 区。 每次都会优先使用 Eden 区,若 Eden 区满,就将对象复制到第二块内存区上,然后清除 Eden 区,如果此时存活的对象太多,以至于 Survivor 不够时,会将这些对 象通过分配担保机制复制到老年代中。(java 堆又分为新生代和老年代)
3)标记-整理 该算法主要是为了解决标记-清除,产生大量内存碎片的问题;当对象存活率较高 时,也解决了复制算法的效率问题。它的不同之处就是在清除对象的时候现将可回 收对象移动到一端,然后清除掉端边界以外的对象,这样就不会产生内存碎片了。
4)分代收集 现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生 代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那 么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担 保,所以可以使用标记-整理 或者 标记-清除。
三.题后思考
JVM的面试题一般都很有难度,需要面试者对JVM有很透彻的理解,不然即使把'八股文背'下来,不能消化理解加实际操作验证那么知道的只是皮毛而已,再深入点就没法回答了。