日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JDK從6update23開始在64位系統(tǒng)上會默認(rèn)開啟壓縮指針

如題。先前都沒仔細(xì)留意,今天在看一個crash log的時候才發(fā)現(xiàn)這點,記錄一下。

成都創(chuàng)新互聯(lián)從2013年創(chuàng)立,先為古縣等服務(wù)建站,古縣等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為古縣企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

本來以為這個是在6 update 25才開始開啟的…

Sun的HotSpot VM從JDK5開始會根據(jù)運行環(huán)境來自動設(shè)定VM的一些參數(shù)(ergonomics)。其中大家最熟悉的可能是它會自動選擇client與server模式、堆的初始和***大小等。事實上ergonomics會設(shè)置非常多的內(nèi)部參數(shù),包括自動選擇GC算法、并行GC的線程數(shù)、GC的工作區(qū)分塊大小、對象晉升閾值等等。

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

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

HotSpot 16:

C++代碼

 
 
 
  1. #ifdef _LP64   
  2.   // Check that UseCompressedOops can be set with the max heap size allocated   
  3.   // by ergonomics.   
  4.   if (MaxHeapSize <= max_heap_for_compressed_oops()) {   
  5.     if (FLAG_IS_DEFAULT(UseCompressedOops)) {   
  6.       // Turn off until bug is fixed.   
  7.       // the following line to return it to default status.   
  8.       // FLAG_SET_ERGO(bool, UseCompressedOops, true);   
  9.     }   
  10.     // ...   
  11.   }   
  12. #endif // _LP64  

HotSpot 17:

C++代碼

 
 
 
  1. #ifndef ZERO   
  2. #ifdef _LP64   
  3.   // Check that UseCompressedOops can be set with the max heap size allocated   
  4.   // by ergonomics.   
  5.   if (MaxHeapSize <= max_heap_for_compressed_oops()) {   
  6. #ifndef COMPILER1   
  7.     if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {   
  8.       // Disable Compressed Oops by default. Uncomment next line to enable it.   
  9.       // FLAG_SET_ERGO(bool, UseCompressedOops, true);   
  10.     }   
  11.   }   
  12. #endif   
  13.   // ...   
  14. #endif // _LP64   
  15. #endif // !ZERO  

HotSpot 19 / HotSpot 20:

C++代碼

 
 
 
  1. #ifndef ZERO   
  2. #ifdef _LP64   
  3.   // Check that UseCompressedOops can be set with the max heap size allocated   
  4.   // by ergonomics.   
  5.   if (MaxHeapSize <= max_heap_for_compressed_oops()) {   
  6. #ifndef COMPILER1   
  7.     if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {   
  8.       FLAG_SET_ERGO(bool, UseCompressedOops, true);   
  9.     }   
  10. #endif   
  11.   }   
  12.   // ...   
  13. #endif // _LP64   
  14. #endif // !ZERO

(注:HotSpot VM的版本號與JDK的版本號之間的關(guān)系,請參考另一篇筆記:Sun/Oracle JDK、OpenJDK、HotSpot VM版本之間的對應(yīng)關(guān)系)

可以看到,UseCompressedOops參數(shù)從HotSpot 19開始終于開始受ergonomics控制,會在下述條件滿足的時候默認(rèn)開啟:

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

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

3、沒有通過.hotspotrc或命令行參數(shù)手動設(shè)定過UseCompressedOops參數(shù)的值;

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

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

還是看回代碼,HotSpot 20:

C++代碼

 
 
 
  1. void set_object_alignment() {   
  2.   // Object alignment.   
  3.   assert(is_power_of_2(ObjectAlignmentInBytes), "ObjectAlignmentInBytes must be power of 2");   
  4.   MinObjAlignmentInBytes     = ObjectAlignmentInBytes;   
  5.   assert(MinObjAlignmentInBytes >= HeapWordsPerLong * HeapWordSize, "ObjectAlignmentInBytes value is too small");   
  6.   MinObjAlignment            = MinObjAlignmentInBytes / HeapWordSize;   
  7.   assert(MinObjAlignmentInBytes == MinObjAlignment * HeapWordSize, "ObjectAlignmentInBytes value is incorrect");   
  8.   MinObjAlignmentInBytesMask = MinObjAlignmentInBytes - 1;   
  9.   
  10.   LogMinObjAlignmentInBytes  = exact_log2(ObjectAlignmentInBytes);   
  11.   LogMinObjAlignment         = LogMinObjAlignmentInBytes - LogHeapWordSize;   
  12.   
  13.   // Oop encoding heap max   
  14.   OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes;   
  15. }   
  16.   
  17. inline uintx max_heap_for_compressed_oops() {   
  18.   // Avoid sign flip.   
  19.   if (OopEncodingHeapMax < MaxPermSize + os::vm_page_size()) {   
  20.     return 0;   
  21.   }   
  22.   LP64_ONLY(return OopEncodingHeapMax - MaxPermSize - os::vm_page_size());   
  23.   NOT_LP64(ShouldNotReachHere(); return 0);   
  24. }  

(注:其中 (uint64_t(max_juint) + 1) 的值也被稱為NarrowOopHeapMax,也就是2的32次方,0x100000000;

ObjectAlignmentInBytes在64位HotSpot上默認(rèn)為8;

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

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

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

跟蹤一下里面幾個參數(shù)的計算,在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上默認(rèn)是:

C++代碼

 
 
 
  1. MaxHeapSize + MaxPermSize + os::vm_page_size() <= 32GB  

os::vm_page_size()是操作系統(tǒng)的虛擬內(nèi)存的分頁大小,在Linux上等于sysconf(_SC_PAGESIZE)的值;在x86_64上的Linux默認(rèn)分頁大小為4KB。

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

MaxPermSize就是perm gen設(shè)置的***大小。

這下可以確認(rèn),在我現(xiàn)在用的環(huán)境里,當(dāng)包括perm gen在內(nèi)的GC堆大小在32GB - 4KB以下的時候,使用64位的JDK 6 update 23或更高版本就會自動開啟UseCompressedOops功能。


當(dāng)前文章:JDK從6update23開始在64位系統(tǒng)上會默認(rèn)開啟壓縮指針
地址分享:http://www.dlmjj.cn/article/dphphgp.html