一、什么是GC?
参考回答:
GC(Generational Collection)是一种分代收集算法,用于释放JVM中那些不再使用的对象所占用的内存。一般常称之为垃圾回收机制。
二、为什么要有GC?
参考回答:
内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。
三、解释一下Java中垃圾收集的主要流程
参考回答:
垃圾收集主要有两种形式:
(1)自动:自动会不定期进行回收,以释放无用的空间。
(2)手工:手工调用的是System类中的gc()方法,此方法实际上调用的是Runtime类中的gc()方法,当一个对象被回收之前将调用类中的finlalize()方法,此方法为 Object类所提供,表示对象回收前的收尾工作。即使出现了异常,也不影响程序的执行,而且此方法抛出的是Throwable,表示可能是异常也可能是错误。
四、垃圾回收的优点和原理。并说出2种回收机制
参考回答:
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。
由于有个垃圾回收机制, Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。
垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
垃圾回收机制 垃圾收集是将分配给对象但不再使用的内存回收或释放的过程。如果一个对象没有指向它的引用或者其赋值为null,则次对象适合进行垃圾回收。
垃圾回收机以低优先级运行
检查不被使用和指向的对象把它删除
五、垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
参考回答:
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。
六、垃圾回收机制的特点?
参考回答:
Java垃圾回收机制的特点是:
(1)垃圾回收机制自动运行
系统提供一个低优先级的线程来跟踪内存的分配情况。如果发现某个内存单元不再使用,就清除它。
(2)何时清除垃圾是不可预期的
当垃圾搜集器运行时,其目的是查找和删除不能被访问的对象。
垃圾收集器运行时,当它发现一个对象不能被任何活线程访问时,它将认为该对象符合删除条件,它可能在某时删除该对象。 垃圾收集器不能保证有足够的内存,它只能保证可以使用的内存将尽可能被有效的管理。
使对象符合垃圾搜集器搜索条件的情况有:
1)出现空引用
2)重新为引用变量赋值
3)隔离引用
4)强制执行垃圾搜集
七、GC的主要任务
参考回答:
(1)分配内存;
(2)确保被引用对象的内存不被错误的回收;
(3)回收不再被引用的对象的内存空间;
八、GC的触发条件
参考回答:
(1)执行System.gc()的时候:建议执行Full GC,但是JVM并不保证一定会执行
(2)新生代空间不足
由于对象大都在Eden区分配内存,如果某个时刻JVM需要给某一个对象在Eden区上分配一块内存,但是此时Eden区剩余的连续内存小于该对象需要的内存,Eden区空间不足会触发minor GC。
触发minor GC前会检查之前每次Minor GC时晋升到老年代的平均对象大小是否大于老年代剩余空间大小,如果大于,则直接触发Full GC;
否则,查看HandlePromotionFailure参数的值,如果为false,则直接触发Full GC;
如果为true(默认为true,表示允许担保失败,虽然剩余空间大于之前晋升到老年代的平均大小,但是依旧可能担保失败),则仅触发Minor GC;
如果期间发生老年代不足以容纳新生代存活的对象,此时会触发Full GC 。
(3)老年代空间不足
大对象直接进入老年代,经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够多的连续空间;
长期存活的对象将进入老年代;
如果survivor空间中相同年龄所有对象大小的总和大于survivor空间的一半,年龄大于等于该年龄的对象就可以直接进入老年代;
CMS GC在出现promotion failure和concurrent mode failure的时候
上面这几种情况会导致“老年代“满”,会触发full GC。
九、你能保证 GC 执行吗?
参考回答:
不能,虽然你可以调用 System.gc() 或者 Runtime.gc(),但是没有办法保证 GC 的执行。
十、为什么不能显示直接调用finalize方法?
参考回答:
finalize方法在垃圾回收时一定会被执行,而如果在此之前显示执行的话,也就是说finalize方法会被执行两次以上,而在第一次资源已经被释放,那么在第二次释放资源时系统一定会报错,因此一般finalize方法的访问权限和父类保持一致,为protected。