<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位系統默認開啟壓縮指針分析(請多多指正!)
          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
  •   (注:HotSpot 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 閱讀(2249) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 8888四色奇米在线观看免费看| 老司机精品免费视频| 久视频精品免费观看99| 亚洲成熟xxxxx电影| 久久久久国色av免费看| 国产亚洲AV无码AV男人的天堂| 成人免费一区二区三区 | 亚洲6080yy久久无码产自国产| 成年女人18级毛片毛片免费| 亚洲性色精品一区二区在线| 日本高清免费aaaaa大片视频| 亚洲a∨无码一区二区| 亚洲国产成人精品91久久久| 一级黄色免费大片| 国产综合精品久久亚洲| 色欲A∨无码蜜臀AV免费播| 亚洲美女自拍视频| 在线观看视频免费国语| 特级av毛片免费观看| 亚洲精品tv久久久久久久久| 久久青草免费91线频观看站街| 亚洲黄色免费电影| 妞干网手机免费视频| 色多多A级毛片免费看| 亚洲VA中文字幕无码一二三区| 91av免费观看| 亚洲Aⅴ在线无码播放毛片一线天| 亚洲成a人片在线观看老师| 国产午夜精品免费一区二区三区| 亚洲视频在线一区二区三区| 成人毛片免费观看视频| 人人公开免费超级碰碰碰视频| 国产亚洲成AV人片在线观黄桃| 和日本免费不卡在线v| 国产亚洲视频在线观看网址| 亚洲精品tv久久久久久久久| 国产a视频精品免费观看| 免费一级毛片在线播放放视频| 久久久久久a亚洲欧洲AV| 天天摸天天碰成人免费视频| 韩国免费A级毛片久久|