欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中垃圾回收器GC對吞吐量的影響測試

 更新時間:2014年09月23日 08:55:28   投稿:junjie  
這篇文章主要介紹了Java中垃圾回收器GC對吞吐量的影響測試,本文算是一個對垃圾回收器GC的優(yōu)化文章,需要的朋友可以參考下

在看內存管理術語表的時候偶然發(fā)現(xiàn)了”Pig in the Python(注:有點像中文里的貪心不足蛇吞象)”的定義,于是便有了這篇文章。表面上看,這個術語說的是GC不停地將大對象從一個分代提升到另一個分代的情景。這么做就好比巨蟒整個吞食掉它的獵物,以至于它在消化的時候都沒辦法移動了。

在接下來的這24個小時里我的頭腦中充斥著這個令人窒息的巨蟒的畫面,揮之不去。正如精神病醫(yī)生所說的,消除恐懼最好的方法就是說出來。于是便有了這篇文章。不過接下的故事我們要講的不是蟒蛇,而是GC的調優(yōu)。我對天發(fā)誓。

大家都知道GC暫停很容易造成性能瓶頸。現(xiàn)代JVM在發(fā)布的時候都自帶了高級的垃圾回收器,不過從我的使用經驗來看,要找出某個應用最優(yōu)的配置真是難上加難。手動調優(yōu)或許仍有一線希望,但是你得了解GC算法的確切機制才行。關于這點,本文倒是會對你有所幫助,下面我會通過一個例子來講解JVM配置的一個小的改動是如何影響到你的應用程序的吞吐量的。

示例

我們用來演示GC對吞吐量產生影響的應用只是一個簡單的程序。它包含兩個線程:

PigEater – 它會模仿巨蟒不停吞食大肥豬的過程。代碼是通過往java.util.List中添加 32MB字節(jié)來實現(xiàn)這點的,每次吞食完后會睡眠100ms。
PigDigester – 它模擬異步消化的過程。實現(xiàn)消化的代碼只是將豬的列表置為空。由于這是個很累的過程,因此每次清除完引用后這個線程都會睡眠2000ms。
兩個線程都會在一個while循環(huán)中運行,不停地吃了消化直到蛇吃飽為止。這大概得吃掉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();
    }
  }
}

現(xiàn)在我們將這個系統(tǒng)的吞吐量定義為“每秒可以消化的豬的頭數(shù)”。考慮到每100ms就會有豬被塞到這條蟒蛇里,我們可以看到這個系統(tǒng)理論上的最大吞吐量可以達到10頭/秒。

GC配置示例

我們來看下使用兩個不同的配置系統(tǒng)的表現(xiàn)分別是什么樣的。不管是哪個配置,應用都運行在一臺擁有雙核,8GB內存的Mac(OS X10.9.3)上。

第一個配置:

1.4G的堆(-Xms4g -Xmx4g)
2.使用CMS來清理老年代(-XX:+UseConcMarkSweepGC)使用并行回收器清理新生代(-XX:+UseParNewGC)
3.將堆的12.5%(-Xmn512m)分配給新生代,并將Eden區(qū)和Survivor區(qū)的大小限制為一樣的。
第二個配置則略有不同:

1.2G的堆(-Xms2g -Xms2g)
2.新生代和老年代都使用Parellel GC(-XX:+UseParallelGC)
3.將堆的75%分配給新生代(-Xmn 1536m)
4.現(xiàn)在是該下注的時候了,哪個配置的表現(xiàn)會更好一些(就是每秒能吃多少豬,還記得吧)?那些把籌碼放到第一個配置上的家伙,你們一定會失望的。結果正好相反:

1.第一個配置(大堆,大的老年代,CMS GC)每秒能吞食8.2頭豬
2.第二個配置(小堆,大的新生代,Parellel GC)每秒可以吞食9.2頭豬

現(xiàn)在我們來客觀地看待一下這個結果。分配的資源少了2倍但吞吐量提升了12%。這和常識正好相反,因此有必要進一步分析下到底發(fā)生了什么。

分析GC的結果

原因其實并不復雜,你只要仔細看一下運行測試的時候GC在干什么就能發(fā)現(xiàn)答案了。這個你可以自己選擇要使用的工具。在jstat的幫助下我發(fā)現(xiàn)了背后的秘密,命令大概是這樣的:

復制代碼 代碼如下:

jstat -gc -t -h20 PID 1s

通過分析數(shù)據(jù),我注意到配置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沒有發(fā)現(xiàn)長期存活的對象時,它能更快地清理掉垃圾對象。而采用第一個配置的話,GC運行的頻率大概會是6到7倍之多,而總的暫停時間則是5至6倍。

說這個故事有兩個目的。第一個也是最主要的一個,我希望把這條抽風的蟒蛇趕緊從我的腦海里趕出去。另一個更明顯的收獲就是——GC調優(yōu)是個很需要技巧的經驗活,它需要你對底層的這些概念了如指掌。盡管本文中用到的這個只是很平常的一個應用,但選擇的不同結果也會對你的吞吐量和容量規(guī)劃產生很大的影響。在現(xiàn)實生活中的應用里面,這里的區(qū)別則會更為巨大。因此,就看你如何抉擇了,你可以去掌握這些概念,或者,只關注你日常的工作就好了,讓Plumbr來找出你所需要的最合適的GC配置吧。

相關文章

  • SpringBoot如何實現(xiàn)定時任務示例詳解

    SpringBoot如何實現(xiàn)定時任務示例詳解

    使用定時任務完成一些業(yè)務邏輯,比如天氣接口的數(shù)據(jù)獲取,定時發(fā)送短信,郵件。以及商城中每天用戶的限額,定時自動收貨等等,這篇文章主要給大家介紹了關于SpringBoot如何實現(xiàn)定時任務的相關資料,需要的朋友可以參考下
    2021-10-10
  • Java實現(xiàn)走迷宮回溯算法

    Java實現(xiàn)走迷宮回溯算法

    這篇文章主要為大家詳細介紹了Java實現(xiàn)走迷宮回溯算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Java生成壓縮文件的實例代碼

    Java生成壓縮文件的實例代碼

    在工作過程中,需要將一個文件夾生成壓縮文件,然后提供給用戶下載。下面通過實例代碼給大家介紹Java生成壓縮文件的方法,感興趣的朋友一起看看吧
    2018-06-06
  • java簡單網頁抓取的實現(xiàn)方法

    java簡單網頁抓取的實現(xiàn)方法

    這篇文章主要介紹了java簡單網頁抓取的實現(xiàn)方法,詳細分析了與Java網頁抓取相關的tcp及URL相關概念,以及對應的類文件原理,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • SpringBoot四種讀取properties文件的方式(小結)

    SpringBoot四種讀取properties文件的方式(小結)

    這篇文章主要介紹了SpringBoot四種讀取properties文件的方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • Java使用join方法暫停當前線程

    Java使用join方法暫停當前線程

    這篇文章主要為大家詳細介紹了Java使用join方法暫停當前線程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java Scala之面向對象

    Java Scala之面向對象

    Scala是一門面向對象的語言。在Scala中,一切皆為對象函數(shù)是對象,數(shù)字也是對象,本文詳細介紹了Scala面向對象的原理和介紹,感興趣的小伙伴可以參考一下
    2023-04-04
  • Java命令行參數(shù)解析工具jcommander詳解

    Java命令行參數(shù)解析工具jcommander詳解

    這篇文章主要為大家介紹了Java命令行參數(shù)解析工具jcommander命令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • java學習:日期的運算代碼

    java學習:日期的運算代碼

    java.util.Date下的很多(構造)方法,已經被標識為"過時"方法,官方推薦使用Calendar類來處理日期的運算,下面是示例:
    2013-02-02
  • Java實戰(zhàn)之電影在線觀看系統(tǒng)的實現(xiàn)

    Java實戰(zhàn)之電影在線觀看系統(tǒng)的實現(xiàn)

    這篇文章主要介紹了如何利用Java實現(xiàn)電影在線觀看系統(tǒng),文中用到的技術有:JSP、Spring、SpringMVC、MyBatis等,感興趣的可以了解一下
    2022-04-04

最新評論