<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    倉藍

    日記本

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      23 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks
       JAVA之JDK在64位系統默認開啟壓縮指針分析(請多多指正?。?br />      Sun的HotSpot VM從JDK5開始會根據運行環境來自動設定VM的一些參數(ergonomics)。其中大家最熟悉的可能是它會自動選擇client與server模式、堆的初始和最大大小等。事實上ergonomics會設置非常多的內部參數,包括自動選擇GC算法、并行GC的線程數、GC的工作區分塊大小、對象晉升閾值等等。

      Ergonomics相關的邏輯大都在hotspot/src/share/vm/runtime/arguments.cpp中,值得留意的是使用了FLAG_SET_ERGO()的地方。

      于是我們可以留意一下幾個版本的HotSpot對UseCompressedOops參數的處理的差異:

      HotSpot 16:

      C++代碼

  • #ifdef _LP64     
  •   // Check that UseCompressedOops can be set with 
    the max heap size allocated   
     
  •   // by ergonomics.     
  •   if (MaxHeapSize <= max_heap_for_compressed_oops()) {     
  •     if (FLAG_IS_DEFAULT(UseCompressedOops)) {     
  •       // Turn off until bug is fixed.     
  •       // the following line to return it to default status.     
  •       // FLAG_SET_ERGO(bool, UseCompressedOops, true);     
  •     }     
  •     // ...     
  •   }     
  • #endif // _LP64
  •   HotSpot 17:

      C++代碼

  • #ifndef ZERO     
  • #ifdef _LP64     
  •   // Check that UseCompressedOops can be set with 
    the max heap size allocated   
     
  •   // by ergonomics.     
  •   if (MaxHeapSize <= max_heap_for_compressed_oops()) {     
  • #ifndef COMPILER1     
  •     if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {     
  •       // Disable Compressed Oops by default. Uncomment 
    next line to enable it.   
     
  •       // FLAG_SET_ERGO(bool, UseCompressedOops, true);     
  •     }     
  •   }     
  • #endif     
  •   // ...     
  • #endif // _LP64     
  • #endif // !ZERO    
  •   HotSpot 19 / HotSpot 20:

      C++代碼

  • #ifndef ZERO     
  • #ifdef _LP64     
  •   // Check that UseCompressedOops can be set with 
    the max heap size allocated   
     
  •   // by ergonomics.     
  •   if (MaxHeapSize <= max_heap_for_compressed_oops()) {     
  • #ifndef COMPILER1     
  •     if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {     
  •       FLAG_SET_ERGO(bool, UseCompressedOops, true);     
  •     }     
  • #endif     
  •   }     
  •   // ...     
  • #endif // _LP64     
  • #endif // !ZERO
  •  ?。ㄗⅲ篐otSpot VM的版本號與JDK的版本號之間的關系,請參考另一篇筆記:Sun/Oracle JDK、OpenJDK、HotSpot VM版本之間的對應關系)

      可以看到,UseCompressedOops參數從HotSpot 19開始終于開始受ergonomics控制,會在下述條件滿足的時候默認開啟管道磁力泵

      1、是64位系統(#ifdef _LP64)并且不是client VM(#ifndef COMPILER1);

      2、Java堆的最大大小不大于一個閾值(MaxHeapSize <= max_heap_for_compressed_oops());

      3、沒有通過。hotspotrc或命令行參數手動設定過UseCompressedOops參數的值;

      4、沒有使用Garbage-First (G1) GC.


    第1、3、4點都很直觀,于是第2點就是個關鍵點了:閾值是多大?

      還是看回代碼,HotSpot 20:

      C++代碼

  • void set_object_alignment() {     
  •   // Object alignment.     
  •   assert(is_power_of_2(ObjectAlignmentInBytes), "ObjectAlignmentInBytes must be power of 2");     
  •   MinObjAlignmentInBytes     = ObjectAlignmentInBytes;     
  •   assert(MinObjAlignmentInBytes >= HeapWordsPerLong * HeapWordSize, 
    "ObjectAlignmentInBytes value is too small");     
  •   MinObjAlignment         = MinObjAlignmentInBytes / HeapWordSize;     
  •   assert(MinObjAlignmentInBytes == MinObjAlignment * HeapWordSize, 
    "ObjectAlignmentInBytes value is incorrect");     
  •   MinObjAlignmentInBytesMask = MinObjAlignmentInBytes - 1;     
  •     
  •   LogMinObjAlignmentInBytes  = exact_log2(ObjectAlignmentInBytes);     
  •   LogMinObjAlignment         = LogMinObjAlignmentInBytes - LogHeapWordSize;     
  •     
  •   // Oop encoding heap max     
  •   OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes;     
  • }     
  •     
  • inline uintx max_heap_for_compressed_oops() {     
  •   // Avoid sign flip.     
  •   if (OopEncodingHeapMax < MaxPermSize + os::vm_page_size()) {     
  •     return 0;     
  •   }     
  •   LP64_ONLY(return OopEncodingHeapMax - MaxPermSize - os::vm_page_size());     
  •   NOT_LP64(ShouldNotReachHere(); return 0);     
  • }
  •  ?。ㄗⅲ浩渲?(uint64_t(max_juint) + 1) 的值也被稱為NarrowOopHeapMax,也就是2的32次方,0x100000000;

      ObjectAlignmentInBytes在64位HotSpot上默認為8;

      HeapWord在globalDefinitions.hpp里定義,大小跟一個char*一樣;

      HeapWordSize在同一個文件里定義,等于sizeof(HeapWord),在64位系統上值為8;

      LogHeapWordSize也在同一文件里,在64位系統上定義為3)

      跟蹤一下里面幾個參數的計算,在64位HotSpot上有,

      C++代碼

    1. ObjectAlignmentInBytes = 8     
    2. MinObjAlignmentInBytes = 8     
    3. HeapWordSize = 8     
    4. MinObjAlignment = 1     
    5. MinObjAlignmentInBytesMask = 0x0111     
    6. LogMinObjAlignmentInBytes = 3     
    7. LogHeapWordSize = 3 // _LP64     
    8. LogMinObjAlignment = 0     
    9. OopEncodingHeapMax = 0x800000000 // 32GB    

      于是,前面提到的第2個條件在64位HotSpot VM上默認是:

      C++代碼

  • MaxHeapSize + MaxPermSize + os::vm_page_size() <= 32GB
  •   os::vm_page_size()是操作系統的虛擬內存的分頁大小,在Linux上等于sysconf(_SC_PAGESIZE)的值;在x86_64上的Linux默認分頁大小為4KB.

      MaxHeapSize的值基本上等于-Xmx參數設置的值(會根據分頁大小、對齊等因素做調整)。

      MaxPermSize就是perm gen設置的最大大小。

      這下可以確認,在我現在用的環境里,當包括perm gen在內的GC堆大小在32GB - 4KB以下的時候,使用64位的JDK 6 update 23或更高版本就會自動開啟UseCompressedOops功能


    posted on 2012-03-02 11:07 cangshi 閱讀(2254) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 亚洲午夜电影在线观看高清 | 亚洲va无码va在线va天堂| 亚洲综合欧美色五月俺也去| 无码国产精品久久一区免费| 色婷五月综激情亚洲综合| 国色精品卡一卡2卡3卡4卡免费| 亚洲男人的天堂久久精品| 国产h视频在线观看免费| 亚洲最大的黄色网| 免费无码又爽又刺激高潮| 亚洲精品精华液一区二区| 午夜小视频免费观看| 精品国产亚洲AV麻豆| 亚洲AV无码一区二三区| 精品国产污污免费网站aⅴ| 亚洲三级电影网站| 2019中文字幕免费电影在线播放| 亚洲午夜精品国产电影在线观看| 性盈盈影院免费视频观看在线一区| 亚洲性色AV日韩在线观看| 亚洲成av人片不卡无码久久| 丝袜捆绑调教视频免费区| 亚洲精品网站在线观看你懂的| 欧美a级成人网站免费| 精品久久亚洲一级α| 在线亚洲97se亚洲综合在线| 色猫咪免费人成网站在线观看| 亚洲人成免费电影| 国产在线19禁免费观看| 亚洲毛片一级带毛片基地| 成人人免费夜夜视频观看| 一个人看的免费视频www在线高清动漫| 亚洲综合熟女久久久30p| 四虎在线成人免费网站| 国产综合成人亚洲区| 亚洲国产精品无码久久一区二区 | 亚洲五月综合缴情婷婷| 亚洲国产成人久久综合野外| 久久免费福利视频| 在线观看亚洲免费| 久久久久亚洲AV无码观看|