面试题
题目来源: https://cloud.tencent.com/developer/article/1628831
- 简述Java垃圾回收机制
- 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
- Java 中都有哪些引用类型?
- 怎么判断对象是否可以被回收?什么时候可以被垃圾回收?
- JVM中的永久代中会发生垃圾回收吗
- 说一下 JVM 有哪些垃圾回收算法?
- 说一下 JVM 有哪些垃圾回收器?
- 详细介绍一下 CMS 垃圾回收器?
- 新生代垃圾回收器和老年代垃圾回收器都有哪些?有什么区别?
- 简述分代垃圾回收器是怎么工作的?
简述Java垃圾回收机制
在java中程序员是不需要手动去管理和释放内存的,JVM中有一个较低级的垃圾回收线程,它会在内存空间不足或是空闲时自动管理和释放内存。jvm会将不再可达的对象添加到要回收的集合当中,进行回收。
垃圾回收器的基本原理是什么?
垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
当对象被创建之初jvm就会去监控这个对象的地址、大小及使用情况,GC会采用有向图的方式记录和管理堆中的对象,通过这种方式判断哪些对象是可达的,哪些对象是不可达的,当对象确认不可达之时GC就可以选择回收这些这个对象的内存空间。
我们可以通过System.gc()
和Runtime.getRuntime().gc()
来通知jvm进行内存回收,但不保证gc操作一定会执行。并且调用这两个方法时通常会出发full gc,所以并不建议频繁调用。
怎么判断对象是否可以被回收?什么时候可以被垃圾回收?
-
引用计数器法:对象在创建之初会被分配一个引用计数器,有对象引用时计数器就+1,引用被释放时-1,当计数器为0时表示该对象没有引用。但该方法不能解决循环引用问题。
-
可达性分析法:从GC Roots对象向下寻找,经过节点的路径被称为引用链,如果一个对象没有任何一条引用链可以达到GC Root对象时该对象就被认为是不可达的,可以被垃圾回收器回收。GC Roots对象有虚拟机栈(本地变量表)中引用的对象,本地方法栈中引用对象,活跃线程引用对象,方法区中静态变量引用的的对象。
JVM中的永久代中会发生垃圾回收吗
在java8之前方法区的实现被称为永久代, 永久代虽然不会进行垃圾回收,但是当永久代内存空间不足或超过临界值时也会触发full GC。
JVM 有哪些垃圾回收算法?
- 标记-清除算法:垃圾回收器会遍历并标记所有无用对象,然后直接进行清除回收。缺点是效率不高,容易产生较多内存碎片,容易导致需要申请连续大块内存时空间不足,导致触发多次GC。
- 复制算法:将内存空间划分为两块,每次存放对象时只放在其中一块内存区域中,当垃圾回收时会复制所有存活对象到另一块内存中,并把原来内存中的所有对象清除。缺点:内存使用率不高。
- 标记-整理算法:标记内存空间中所有可用对象,并把它们都移动到内存的一端,然后直接清除掉端边界以外内存。缺点是需要多次遍历并且重新定位标记,当存活对象数量过多时效率很低。
- 分代回收算法:将内存空间划分为新生代和老年代,新生代的对象每经历一次gc后,存活的对象年龄会+1,当年龄超过一定的阈值(默认为15)会被移动到老年代中去。
说一下 JVM 有哪些垃圾回收器?
新生代:serial(串行), parNew(并行),parallel scanvenge(并行)。全都为复制算法。 老年代:serial old(标记整理,串行), parallel old(标记整理,并行), CMS(标记回收,并发)。 新生代&老年代:G1(复制算法&标记整理算法,并行、并发回收)
详细介绍一下 CMS 垃圾回收器?
分代回收算法
JVM内存新生代Eden区和Survivor区的比例是8:1:1 新生代和老年代的比例默认为1:2
Minor GC(young GC)、Major GC、Full GC
https://cloud.baidu.com/article/3185254
当年轻代(Eden区)满时就会触发 Minor GC,这里的年轻代满指的是 Eden区满。Survivor 满不会触发 Minor GC 。
从年轻代空间(主要是 Eden区)回收内存被称为 Minor GC。
CMS收集器中,当老年代满时会触发 Major GC。
目前,只有CMS收集器会有单独收集老年代的行为。其他收集器均无此行为。
Full GC 对收集整堆(新生代、老年代)和方法区的垃圾收集。
当年老代满时会引发Full GC,Full GC将会同时回收新生代、年老代 ;
当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载 。