"葬儀" Javaオブジェクト - ガベージコレクション(B)

1ファイナライズについて話をします()

確定すべての作業を()行うことができ、使用のtry-最後に、私はあなたが完全にこのアプローチの存在下で、Java言語を忘れることを示唆しているので、よりタイムリーに、より良い行うことができますまたはそれ以外の場合は。

- 「JVMの深い理解」

  ファイナライズ()メソッドは、実際に自己の目的を達成することができるが、その不確実性高価なランニングコストが、この方法は非常に慎重に使用する必要があることを示しています。そして、ファイナライズ()関数は、どのような期間、どのように自助それの目的を達成するには?まず、オブジェクトを直接回復していないときに、死への仮想マシンのスキャンを理解する必要がありますが、一度マーキングおよびスクリーニング、条件をスクリーニングすると、そのオブジェクトでファイナライズ行う必要があるかどうかの方法。現在のオブジェクトが場合はファイナライズメソッドをオーバーライドしないか、すでにファイナライズ方法一度呼ばれてきた、実行する必要はないとみなされ、自分自身を保存する機会を失うことになる今回は、コレクションを「回復する」に置きます。

  そうでない場合、オブジェクトはと呼ばれる場所に配置されているF-キューキュー、仮想マシンは、後で実行キュー・オブジェクトの一つとなりファイナライズオブジェクトができる場所、ある方法(ファイナライズチェーン方法でそれらに関連する参照を、一時的に)リサイクルされるの運命から逃れるために、それは仮想マシンの実施を確保するのではなく、完全な実行を保証するものではなく、ファイナライズ場合ので、メソッドをファイナライズ無限ループの実行方法が長すぎるか秋にかかる、あなたはシステムの崩壊ベンをさせることができます。すべてを実行した後チェーンへのGGの参照でない場合、仮想マシンは、キューに一度再マークの対象となる、またはコレクションを「回復する」それを動かします。セルフヘルプとセルフヘルプを達成するための「JVMの深い理解」を参照して、以下の例では、唯一のプロセス一度確認することができます。

パブリック クラスTestForGcは{ 

    / ** 静的変数のルートノードの定義* / 
    パブリック 静的TestForGcインスタンス; 

    / ** 
     *オーバーライドファイナライズ処理はFQ結合を実行させ、必要に応じて標識されている
     * 
     * @throws のThrowable
      * / 
    @Overrideを
    保護された ボイドファイナライズ()スローされたThrowable {
         スーパー.finalizeを(); 
        System.err.println(「呼び出さTestForGcクラスでファイナライズメソッド!」);
         //は、ルートノードに自己の実現自体を関連付ける 
        インスタンス= この; 
    } 

    公共の 静的 空隙メイン(文字列[]引数)がスローInterruptedExceptionある{ 
        INSTANCE = 新しい新しいTestForGcを(); 

        INSTANCE = NULL ; 
        にSystem.gc(); 
        // スリープ1S、FQの保証方法は終了 
        TimeUnit.SECONDS.sleepを(1 )、
         IF ( Objects.nonNull(INSTANCE)){ 
            System.out.printlnは( "I首尾自分で保存ファイナライズ方法!" ); 
        } { 
            System.out.printlnは( "デッド:( I AM" ); 
        } 

        / * 
         *次の検証finalizeメソッドは一度だけ呼び出すことができます
         *ほぼ正確に同じコードが、それは違う結末であります
         * / 
        INSTANCE = nullを
        System.gc(); 
        // 睡眠1S 
        TimeUnit.SECONDS.sleep(1 )。
        もし(Objects.nonNull(INSTANCE)){ 
            System.out.printlnは( "!私は成功し、再びファイナライズの方法で自分自身を救います" ); 
        } { 
            System.out.printlnは( "私は死んだ:(、ファイナライズ再起動することができませんでした" ); 
        } 
    } 
} 
执行结果:

 2ガベージコレクタ

  回復アルゴリズムがインターフェイスである場合には、ガベージコレクタは、インタフェースクラスの実装で、コレクタの7種類の合計は、それらをリストアップ。

2.1シリアルガベージコレクタ

  シリアルは「つまり、仕事はすべてのユーザーのスレッドを一時停止する時間で、シングルスレッドのガベージコレクタでSTOP-で世界のユーザーに代わってシングルスレッドがすることは、」それはである必要はないというスレッドを一時停止するだけでなく、手段対話型のスレッドは、このように高い捕集効率を持っています。シリアル使用してレプリケーションアルゴリズムがあるクライアントのデフォルトのガベージコレクタの側の新世代。図は、それは次のように動作します:

2.2 ParNewガベージコレクタ。

  ParNewがあるシリアル、コレクタのマルチスレッドバージョンでサーバ側のデフォルトコレクタ新世代の、マルチスレッド平行に加えて、他を含む実装が正確に同じである、もちろん、複製アルゴリズムを使用します。これは、に加えて、コレクターの新世代のことも重要であるシリアル、追加のみParNewの古い世代に話CMSのコラボレーション、効率はシリアルよりも低いCPUの場合には低いが、複数のCPUの場合にはるかに優れていますそしてより多くの。その作業の図:

2.3パラレルスカベンジガベージコレクタ

  跟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.

おすすめ

転載: www.cnblogs.com/zhangweicheng/p/11809376.html