程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java中渣滓收受接管器GC對吞吐量的影響測試

Java中渣滓收受接管器GC對吞吐量的影響測試

編輯:關於JAVA

Java中渣滓收受接管器GC對吞吐量的影響測試。本站提示廣大學習愛好者:(Java中渣滓收受接管器GC對吞吐量的影響測試)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中渣滓收受接管器GC對吞吐量的影響測試正文


在看內存治理術語表的時刻有時發明了”Pig in the Python(注:有點像中文裡的貪婪缺乏蛇吞象)”的界說,因而便有了這篇文章。外面上看,這個術語說的是GC一直地將年夜對象從一個分代晉升到另外一個分代的情形。這麼做就比如巨蟒全部吞食失落它的獵物,以致於它在消化的時刻都沒方法挪動了。

在接上去的這24個小時裡我的腦筋中充滿著這個使人梗塞的巨蟒的畫面,揮之不去。正如精力病大夫所說的,清除恐怖最好的辦法就是說出來。因而便有了這篇文章。不外接下的故事我們要講的不是蟒蛇,而是GC的調優。我對天起誓。

年夜家都曉得GC暫停很輕易形成機能瓶頸。古代JVM在宣布的時刻都自帶了高等的渣滓收受接管器,不外從我的應用經歷來看,要找出某個運用最優的設置裝備擺設真是難上加難。手動調優也許仍有一線願望,然則你得懂得GC算法切實其實切機制才行。關於這點,本文卻是會對你有所贊助,上面我會經由過程一個例子來說解JVM設置裝備擺設的一個小的修改是若何影響到你的運用法式的吞吐量的。

示例

我們用來演示GC對吞吐量發生影響的運用只是一個簡略的法式。它包括兩個線程:

PigEater – 它會模擬巨蟒一直吞食年夜肥豬的進程。代碼是經由過程往java.util.List中添加 32MB字節來完成這點的,每次吞食完後會睡眠100ms。
PigDigester – 它模仿異步消化的進程。完成消化的代碼只是將豬的列表置為空。因為這是個很累的進程,是以每次消除完援用後這個線程都邑睡眠2000ms。
兩個線程都邑在一個while輪回中運轉,一直地吃了消化直到蛇吃飽為止。這年夜概得吃失落5000頭豬。


package eu.plumbr.demo;

public class PigInThePython {
  static volatile List pigs = new ArrayList();
  static volatile int pigsEaten = 0;
  static final int ENOUGH_PIGS = 5000;

  public static void main(String[] args) throws InterruptedException {
    new PigEater().start();
    new PigDigester().start();
  }

  static class PigEater extends Thread {

    @Override
    public void run() {
      while (true) {
        pigs.add(new byte[32 * 1024 * 1024]); //32MB per pig
        if (pigsEaten > ENOUGH_PIGS) return;
        takeANap(100);
      }
    }
  }

  static class PigDigester extends Thread {
    @Override
    public void run() {
      long start = System.currentTimeMillis();

      while (true) {
        takeANap(2000);
        pigsEaten+=pigs.size();
        pigs = new ArrayList();
        if (pigsEaten > ENOUGH_PIGS)  {
          System.out.format("Digested %d pigs in %d ms.%n",pigsEaten, System.currentTimeMillis()-start);
          return;
        }
      }
    }
  }

  static void takeANap(int ms) {
    try {
      Thread.sleep(ms);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

如今我們將這個體系的吞吐量界說為“每秒可以消化的豬的頭數”。斟酌到每100ms就會有豬被塞到這條蟒蛇裡,我們可以看到這個體系實際上的最年夜吞吐量可以到達10頭/秒。

GC設置裝備擺設示例

我們來看下應用兩個分歧的設置裝備擺設體系的表示分離是甚麼樣的。不論是哪一個設置裝備擺設,運用都運轉在一台具有雙核,8GB內存的Mac(OS X10.9.3)上。

第一個設置裝備擺設:

1.4G的堆(-Xms4g -Xmx4g)
2.應用CMS來清算老年月(-XX:+UseConcMarkSweepGC)應用並行收受接管器清算重生代(-XX:+UseParNewGC)
3.將堆的12.5%(-Xmn512m)分派給重生代,並將Eden區和Survivor區的年夜小限制為一樣的。
第二個設置裝備擺設則略有分歧:

1.2G的堆(-Xms2g -Xms2g)
2.重生代和老年月都應用Parellel GC(-XX:+UseParallelGC)
3.將堆的75%分派給重生代(-Xmn 1536m)
4.如今是該下注的時刻了,哪一個設置裝備擺設的表示會更好一些(就是每秒能吃若干豬,還記得吧)?那些把籌馬放到第一個設置裝備擺設上的家伙,你們必定會掉望的。成果正好相反:

1.第一個設置裝備擺設(年夜堆,年夜的老年月,CMS GC)每秒能吞食8.2頭豬
2.第二個設置裝備擺設(小堆,年夜的重生代,Parellel GC)每秒可以吞食9.2頭豬

如今我們來客不雅地對待一下這個成果。分派的資本少了2倍但吞吐量晉升了12%。這和知識正好相反,是以有需要進一步剖析下究竟產生了甚麼。

剖析GC的成果

緣由其實其實不龐雜,你只需細心看一下運轉測試的時刻GC在干甚麼就可以發明謎底了。這個你可以本身選摘要應用的對象。在jstat的贊助下我發明了面前的機密,敕令年夜概是如許的:

jstat -gc -t -h20 PID 1s

經由過程剖析數據,我留意到設置裝備擺設1閱歷了1129次GC周期(YGCT_FGCT),總共花了63.723秒:


Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
594.0 174720.0 174720.0 163844.1  0.0   174848.0 131074.1 3670016.0  2621693.5  21248.0 2580.9   1006   63.182  116 0.236   63.419
595.0 174720.0 174720.0 163842.1  0.0   174848.0 65538.0  3670016.0  3047677.9  21248.0 2580.9   1008   63.310  117 0.236   63.546
596.1 174720.0 174720.0 98308.0 163842.1 174848.0 163844.2 3670016.0   491772.9  21248.0 2580.9   1010   63.354  118 0.240   63.595
597.0 174720.0 174720.0  0.0   163840.1 174848.0 131074.1 3670016.0   688380.1  21248.0 2580.9   1011   63.482  118 0.240   63.723

第二個設置裝備擺設一共暫停了168次(YGCT+FGCT),只花了11.409秒。


Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
539.3 164352.0 164352.0  0.0    0.0   1211904.0 98306.0   524288.0   164352.2  21504.0 2579.2 27    2.969  141 8.441   11.409
540.3 164352.0 164352.0  0.0    0.0   1211904.0 425986.2  524288.0   164352.2  21504.0 2579.2 27    2.969  141 8.441   11.409
541.4 164352.0 164352.0  0.0    0.0   1211904.0 720900.4  524288.0   164352.2  21504.0 2579.2 27    2.969  141 8.441   11.409
542.3 164352.0 164352.0  0.0 0.0   1211904.0 1015812.6  524288.0   164352.2  21504.0 2579.2 27 2.969  141 8.441   11.409

斟酌到兩種情形下的任務量是同等的,是以——在這個吃豬的試驗中當GC沒有發明歷久存活的對象時,它能更快地清算失落渣滓對象。而采取第一個設置裝備擺設的話,GC運轉的頻率年夜概會是6到7倍之多,而總的暫停時光則是5至6倍。

說這個故事有兩個目標。第一個也是最重要的一個,我願望把這條抽風的蟒蛇趕忙從我的腦海裡趕出去。另外一個更顯著的收成就是——GC調優是個很須要技能的經歷活,它須要你對底層的這些概念管窺蠡測。雖然本文頂用到的這個只是很平凡的一個運用,但選擇的分歧成果也會對你的吞吐量和容量計劃發生很年夜的影響。在實際生涯中的運用外面,這裡的差別則會更加偉大。是以,就看你若何決定了,你可以去控制這些概念,或許,只存眷你平常的任務就行了,讓Plumbr來找出你所須要的最適合的GC設置裝備擺設吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved