同学好,
就跟视频里说的一样,我们GC有两种,年轻代的GC和老年代GC,一般多久发生一次GC这个得看GC的触发条件。而且同学,咱们视频里全都说了呀,仔细看看就会有答案了。。。
视频里这样回答问题二的。。
对象在 Survivor 区每熬过一次 Minor GC,其年龄就会被 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来调整这个岁数 ),这些对象就会成为老年代。 但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间的对象 ) 则是直接进入到老年代。
对于问题一:
什么情况下会触发Full GC呢?
触发FullGC可以通过满足以下的任一条件去触发:
1. 老年代空间不足:如果创建一个大对象,Eden区域当中放不下这个大对象,会直接保存在老年代当中,如果老年代空间也不足,就会触发Full GC。为了避免这种情况,最好就是不要创建太大的对象。
2. 永久代空间不足,这仅仅是针对jdk7及以前的版本,当系统中需要加载的类,调用的方法很多,同时持久代当中没有足够的空间,就出触发一次Full GC。而jdk8以后,由于取消了永久代,该条件不成立,这也是为什么要用元空间替代永久代的原因,为的是降低FullGC的频率,减少GC的负担,提升其效率
3. CMS GC时出现promotion failed和concurrent mode failure:对于采用CMS进行老年代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能会触发Full GC。 promotionfailed是在进行Minor GC时,survivor space放不下、对象只能放入旧生代,而此时老年代也放不下造成的;concurrent mode failure是在执行CMS GC的过程中同时有对象要放入旧生代,而此时老年代空间不足造成的。关于CMS收集器,我们马上就会讲到。
4. 统计得到的Minor GC晋升到老年代的平均大小大于老年代的剩余空间。这是一个较为复杂的触发情况,Hotspot为了避免由于新生代对象晋升到老年代导致老年代空间不足的现象,在进行Minor GC时,做了一个判断,如果之前统计所得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间,那么就直接触发Full GC。例如程序第一次触发MinorGC后,有6MB的对象晋升到旧生代,那么当下一次Minor GC发生时,首先检查老年代的剩余空间是否大于6MB,如果小于6MB,则执行Full GC。
5. System.gc():在程序里直接调用System.gc()会显式直接触发Full GC,同时对老年代和新生代进行回收。这里需要注意的是,这个方法只是提醒虚拟机,码农希望你在这回收一下对象,但回不回收还是虚拟机来决定,也就是说码农对回不回收没有绝对的控制权
6. 对于使用RMI来进行RPC或管理的Sun JDK应用而言,默认情况下会一小时执行一次Full GC
Minor GC触发条件:
当Eden区满时,触发Minor GC。