"Funerals" Java objects - garbage collection (b)

1 to talk about Finalize ()

finalize all the work () can do, using the try-finally or otherwise can do better, more timely, so I suggest that you completely forget about the Java language in the presence of this approach.

- "in-depth understanding of JVM"

  finalize () method can indeed achieve a self object, but its uncertainty and expensive running costs indicate that this method requires the use of very careful. Then finalize () function in what period and how to achieve the object of self-help it? First we have to understand the virtual machine scan to death when the object is not directly recovered, but once marking and screening , screening conditions is its object finalize method whether it is necessary to perform. If the current object does not override finalize method or has already been called once finalize method , then it is deemed not necessary to perform, this time will lose the opportunity to save themselves, put "will recover" collection.

  Otherwise, the object is placed in a place called F-Queue queue, the virtual machine will be one of the later execution queue object finalize method (that is, where the object can finalize their associated references in the chain method, to temporarily escape the fate of being recycled), it should be noted that to ensure the implementation of the virtual machine but does not guarantee the complete execution finalize method, because if finalize an infinite loop execution method takes too long or fall, you can let the system collapse Ben. After performing all, the virtual machine will be subject to re-mark the queue once, if not in the GG reference to the chain, or move it out "will recover" collection. The following example with reference to "in-depth understanding of JVM" to achieve self-help and self-help can only be verified once the process.

public class TestForGc {

    / * Define a static variable root node * / 
    public  static TestForGc INSTANCE;

    /**
     * Override finalize method, it is necessary to let it be marked as executed and added FQ
     *
     * @throws Throwable
     */
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.err.println ( "Class TestForGc the Finalize Method, in the Invoked!" );
         // will associate itself to the root node, the realization of self-help 
        INSTANCE = the this ;
    }

    public static void main(String[] args) throws InterruptedException {
        INSTANCE = new TestForGc();

        INSTANCE = null;
        System.gc();
        // Sleep 1S, assurance method of FQ finished 
        TimeUnit.SECONDS.sleep (. 1 );
         IF (Objects.nonNull (INSTANCE)) {
            System.out.println("i successfully save myself by finalize method!");
        } else {
            System.out.println("i am dead :(");
        }

        /*
         * Verify finalize the following method can be called only once
         * Almost exactly the same code, but it is a different ending
         */
        INSTANCE = null;
        System.gc();
        // 睡眠1S
        TimeUnit.SECONDS.sleep(1);
        if (Objects.nonNull(INSTANCE)) {
            System.out.println("i successfully save myself by finalize method again!");
        } else {
            System.out.println("couldn't invoke finalize again, i am dead :(");
        }
    }
} 
The results:

 2 garbage collector

  If the recovery algorithm is the interface, then the garbage collector is the implementation of the interface class, a total of seven kinds of collector, then list them.

2.1 Serial garbage collector

  Serial is a single-threaded garbage collector, at the time when the work will suspend all user threads, that is, " STOP-at The-world ", although single-threaded on behalf of the user pauses the thread, but also means that it need not be interactive thread thus has a higher collection efficiency. Serial using replication algorithm is Client -side new generation of default garbage collector. Figure it work like this:

2.2 ParNew garbage collector.

  ParNew is Serial multi-threaded version of the collector, is the Server -side default collector of new generation, in addition to parallel multi-threaded, the other including implementations are exactly the same, of course, also use replication algorithm. It is also important that the new generation of collectors in addition to Serial addition, only ParNew talk to the old generation of CMS collaboration, efficiency is low in the case of low CPU than Serial, but in the case of more than one CPU is much better many. Its working diagram:

2.3 Parallel Scavenge garbage collector

  跟ParNew类似,作用于新生代,并行多线程并且也是采用复制算法。但是其关注的点却不同,其着重的是一种叫做"吞吐量"的东西。所谓的"吞吐量"=运行用户代码的时间 / (运行用户代码的时间 + GC时间),也就是说其更加注重用户代码运行时间不是减少GC停顿时间。相对于其他收集器来说,可以更加高效的利用CPU,更加适合作为在后台运算而不大需要交互的任务。Parallel收集器提供了两个比较重要的参数。

-XX:MaxGCPauseMillis:表示收集器将尽可能的在这个参数设定的毫秒数内完成回收工作。但这并不代表其设置的越低越好,缩减回收时间是通过减少吞吐量换来的,如果设置得太低可能导致频繁的GC。

-XX:GCTimeRatio:表示代码运行时间和垃圾回收时间的比率,比如说设置为19,那么则垃圾回收时间占比为 1 / (1+19) = 5%,默认是99。

2.4 Serial Old垃圾回收器

  Serial的年老代版本,同Serial基本相似,不同的是采用的是标记-整理算法实现,作为Client端默认的年老代收集器。如果在Server端的话,那么其主要作用有二:

 1、跟新生代的Parallel Scavenge收集器配合。

 2、做一个有价值的"备胎":当CMS垃圾回收器因为预留空间问题放不下对象而发生Concurrent Mode Fail时,作为其备选方案执行垃圾回收。

 

2.5 Parallel Old垃圾回收器

  Parallel Scavenge的年老代版本,多线程并行,同样注重吞吐量,使用标记-整理算法。这个收集器可以跟新生代的Parallel Svavenge一起搭配使用,在注重吞吐量和CPU资源敏感的场合中是一对很好的组合。

2.6 CMS垃圾回收器

  来了,它来了!CMS垃圾回收器被当做是具有划时代意义的、真正实现并发的垃圾回收器,总而言之=》

  ,--^----------,--------,-----,-------^--,

  | ||||||||| `--------' | O

  `+---------------------------^----------|

  `\_,-------, _______________________强__|

  / XXXXXX /`| /

  / XXXXXX / `\ /

  / XXXXXX /\______(

  / XXXXXX /

  / XXXXXX /

  (________(

   `------'

  CMS是一款并发的垃圾回收器,但并不代表全程都不需要停顿,只是大部分时间是跟用户线程一起执行的。其整个GC过程中总共有4个阶段。

1、初始标记:简单的标记所有的根节点,需要暂停所有的用户线程,即"stop-the-world",耗时较短。关于GCRooots的过程可以看下另一篇文章——垃圾回收(一)

2、并发标记:跟用户线程一起工作,寻找堆中的死亡对象,整个过程耗时最长。

3、重新标记:再次扫描,主要对象是并发标记过程中又新增的对象,也就是验漏。多线程,需要STW,时间相对并发标记来说短。

4、并发清除:GC线程跟用户线程一起执行,清除标记的死亡对象,"浮动垃圾"在此阶段产生。

  然而,优秀如CMS也会有不足之处,总共四个阶段的标记及清除算法的实现必定为其带来一些使用的麻烦。

缺点:

  1、占用一定CPU资源:其有两个阶段需要并发跟用户线程一起执行,也就是说要跟用户线程抢占CPU的时间片,会占用一定的CPU资源,如果CPU资源不太优质的情况下,可能会造成不小的影响。

  2、空间利用率不能达到最大:由于并发清除时用户线程也在运行,那么在GC结束前必定会产生一些额外的垃圾,那么就必须给这些垃圾预留一定的空间,否则会导致内存不足从而报"Concurrent Mode Failure",此时虚拟机便启用后备方案——使用Serial Old来进行垃圾回收,进而浪费更多的时间。

  3、内存碎片导致提前FullGC:CMS采用的是标记-清除算法,也就是说会产生内存碎片,那么可能出现大对象放不下的情况,进而不得不提前进行一次FullGC。为了解决这个问题,虚拟机提供了两个参数-XX:+UseCMSCompactAtFullCollection-XX:CMSFullGCsBeforeCompaction,分别表示CMS顶不住要进行FullGC的时候进行内存的整理(整理的过程中无法并发,停顿时间不得不变长) 和进行多少次不压缩的FullGC之后来一次整理的GC(默认0次,表示每次都进行内存整理)。

2.7 G1垃圾回收器

  G1是一个新秀垃圾回收器,被赋予了很大的使命——取代CMS。G1作为新时代的垃圾回收器,相对于其他垃圾回收器来说有许多优势。

1、并行和并发:G1可以利用现在的硬件优势,缩短GC时stop-the-world的停顿时间,并且GC的时候同时也能让用户线程执行。

2、分代收集:跟其他垃圾回收器不同,G1没有物理上的年老代和新生代,其将内存分成了多个独立的Region,每个Region都可能表示属于新生代还是年老代,所以不需要一堆Region凑放在一起然后将这块区域称作新生代,它们之间并不需要连续,所以只有概念上的分代,也是这种分代方式使得G1可以独立管理这个堆空间,不需要跟其他回收器合作。

3、空间整合:G1的算法从Region层面看属于复制算法(从一个Region复制到另一个),但是从整体看又是标记-整理法。然而不管是哪种,都表示G1不会产生内存碎片,不会因为空间不连续放不下大对象而出现FullGC的情况。

  G1回收器将内存空间分成若干个Region,并且这些Region之前相互独立。但是我们都知道这并不能真正的独立,因为一个Region中的对象不一定只会被当前Region的其他对象引用,而可能被堆中的其他对象引用,那G1是如何实现避免全堆扫描的呢?这个问题在分代的其他回收器中也有,但是在这里突显得更加明显而已。再G1中,对象本身都会有一个Remembered Set,这个Set存放着当前对象被其他区域对象引用的信息,这样子,在扫描引用的时候加上这个Set就可以避免全堆扫描了。

  具体实现大致为:虚拟机在发现程序正在进行对Reference类型的写操作时,会暂时中断写操作,然后检查Reference引用的对象是否处于不同的区域如果是分代,则只对年老代的对象进行检查,检查是否引用的对象在新生代),如果是的话则将引用信息记录在被引用的Remembered Set中,这样在GC的时候加上Remembered Set的扫描就可以避免全堆扫描了。

  跟CMS类型,G1也有四个阶段(不算Remembered Set的扫描),虽然相似但是还是有些区别的。

1、初始标记:标记可达的根节点,STW,单线程,时间短。

2、并发标记:跟用户线程同时执行,并发执行时对象可能会产生引用变化,其会将这些变化记录在Remembered Set Logs中,待下个阶段整合。

3、最终标记:验漏,将并发标记阶段的引用变化记录Remembered Set Logs整合到Remembered Set中。

4、筛选回收:对各个Region中的回收价值进行排序,然后执行回收计划。暂停用户线程,并行执行。 

3 小结

  本文首先介绍了“对象自救”的方法——finalize,并且用一个小例子演示了对象如何实现自救。接着介绍了7种不同的垃圾回收器,新生代中有单线程的Serial可以作为Client端新生代的默认回收器,有多线程版本的Serial——ParNew,还有着重点不同(吞吐量)的Parallel Scavenge;年老代方面有单线程的Serial Old、跨时代意义的并发回收器——CMS,虽然优秀还是其使用的算法和实现导致了它的三个缺点、还有吞吐量年老代版本——Parallel Old收集器,最后还简单介绍了G1收集器的几个过程还有独立的Region间是如何实现避免堆扫描的。

  整体下来整篇行文还有些粗糙,日后会慢慢的圆润,如果有关于这方面好的文章可以在下面评论区分享学习一下,下方为各个垃圾回收器的搭配图。

 

 

It helps me a lot if you could share your opinion with us.

Guess you like

Origin www.cnblogs.com/zhangweicheng/p/11809376.html