1、在什么时候触发GC


 

     GC分为① Minor GC(针对新生代的GC) ② Full GC(清理整个堆空间—包括年轻代和永久代)。

  • Minor GC 的触发条件是:大多数情况,新生对象在Eden区分配,当Eden区空间不足时就触发Minor GC。清除非存活对象,将存活对象放到幸存者区,然后整理幸存者的两个区。
  • Full GC触发条件是:①老年代空间不足②持久带空间不足③调用System.gc的时候④GC担保失败。

GC担保失败

  • GC担保失败就是一个空间分配的担保问题
  • 每次调用Minor GC之前先判断老年代的最大可用连续空间是否大于新生代所有对象的总空间,如果大于就Minor GC,如果小于就查看配置是否允许担保失败,不允许就直接Full GC。如果允许担保失败,就判断老年代最大的可用连续空间是否大于历史平均晋升到老年代对象的大小,大于则Minor GC,小于则Full GC。

 


2、对什么东西清除


 

  • GC找寻什么对象会被回收是先通过可达性分析算法,从GC Roots开始往下找引用节点,再找这个引用节点下面的引用节点,直到全部找完,其中没有引用的结点又叫无用结点,将会被标记为可回收对象,但可回收对象不表示他立即被回收,而是经过两次标记后才会被回收,第一次标记是看它有没有重写finalize()方法,没有重写,则被第二次标记然后回收。否则,若对象重写finalize()方法但未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize()方法。执行finalize()方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”(如果对象在finalize()方法中重新和引用链重新建立联系,那么他会逃脱回收,继续存活)。

 

     

gc java什么时候触发young java gc触发条件_gc java什么时候触发young

哪些对象可以作为GC Roots?

  • 虚拟机栈(栈帧中的本地变量表)中的引用的对象
  • 方法区中的类静态属性引用的对象
  • 方法区中的常量引用的对象
  • 本地方法栈中JNI(Native方法)的引用对象

 


GC在收集一个对象的时候会判断是否有引用指向对象,在JAVA中的引用主要有四种:

  • 强引用:不会被垃圾回收器回收,内存不足时,jvm抛出oom错误都不会随意回收强引用(想回收的话,把引用赋值为null)
  • 软引用:内存空间足够时不会被回收,内存空间不足时,会被垃圾回收器回收
  • 弱引用:垃圾回收器运行时,弱引用会被回收
  • 虚引用:相当于没有引用,任何时候都会被回收

     finalize()方法

  • finalize()方法只会被调用一次,如果一个在 finalize 被拯救的对象再次需要回收,则它的 finalize 将不会再被触发了。
  • 不建议使用finalize 方法,它的运行代价高,不确定性大,GC 也不会等待它执行完成,它的功能完全可以被 try-finally 代替。

3、做了什么事情


 

  GC回收算法:目前大部分JVM的垃圾收集器采用的算法是:分代收集算法。

  • 分代收集算法的思想是根据对象存活的生命周期将内存划分为若干个区域。其中,堆中分为年轻代和老年代,除了堆以外还有一个持久代。年轻代中有Eden区,和幸存者1区,幸存者0区。它垃圾收集算法用的是复制算法。老年代有可能采用标记-整理法,有可能采用标记-清除法。
  • 复制算法(复制清理算法):
  • 将内存分为两块相等的空间,先只用其中一块,当这块空间满了的时候再将这块空间中的对象复制到另一块空间,然后清理这块空间。这样不容易出现内存碎片问题。
  • 优点:能够挪出大块的空间
  • 缺点:浪费空间,移动数据浪费时间
  • 标志-清除法:
  • 从GC Roots开始对存活的对象进行标记,全部标记完毕后,扫描整个空间找出未被标记的对象回收
  • 优点:实现简单
  • 缺点:由于未经过整理,所以导致很多内存碎片,分配大对象时候可能会造成"Out of Memory"(内存不足)的情况。可用空间不连续
  • 标志-整理法:
  • 和标记-清除法不同,在标记完成后,他不是回收未标记对象,而是将标记对象挪到一端,然后清理除端边界以外的对象
  • 优点:由于标记后继续整理,不会产生内存碎片而且不需要预留空间
  • 缺点:数据移动会浪费时间