阀体厂家
免费服务热线

Free service

hotline

010-00000000
阀体厂家
热门搜索:
成功案例
当前位置:首页 > 成功案例

看一看:JDK从6 update 23开始在64位系统上会默认开启压缩指针

发布时间:2022-04-02 10:10:31 阅读: 来源:阀体厂家
JDK从6 update 23开始在64位系统上会默认开启压缩指针 作者:RednaxelaFX 2011-04-22 09:35:18 开发 后端 如题。先前都没仔细留意,今天在看一个crash log的时候才发现这点,记录一下。 本来以为这个是在6 update 25才开始开启的…

如题。先前都没仔细留意,今天在看一个crash log的时候才发现这点,记录一下。

本来以为这个是在6 update 25才开始开启的…

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++代码

  1. #ifdef_LP64
  2. //CheckthatUseCompressedOopscanbesetwiththemaxheapsizeallocated
  3. //byergonomics.
  4. if(MaxHeapSize<=max_heap_for_compressed_oops()){
  5. if(FLAG_IS_DEFAULT(UseCompressedOops)){
  6. //Turnoffuntilbugisfixed.
  7. //thefollowinglinetoreturnittodefaultstatus.
  8. //FLAG_SET_ERGO(bool,UseCompressedOops,true);
  9. }
  10. //...
  11. }
  12. #endif//_LP64

HotSpot 17:

C++代码

  1. #ifndefZERO
  2. #ifdef_LP64
  3. //CheckthatUseCompressedOopscanbesetwiththemaxheapsizeallocated
  4. //byergonomics.
  5. if(MaxHeapSize<=max_heap_for_compressed_oops()){
  6. #ifndefCOMPILER1
  7. if(FLAG_IS_DEFAULT(UseCompressedOops)&&!UseG1GC){
  8. //DisableCompressedOopsbydefault.Uncommentnextlinetoenableit.
  9. //FLAG_SET_ERGO(bool,UseCompressedOops,true);
  10. }
  11. }
  12. #endif
  13. //...
  14. #endif//_LP64
  15. #endif//!ZERO

HotSpot 19 / HotSpot 20:

C++代码

  1. #ifndefZERO
  2. #ifdef_LP64
  3. //CheckthatUseCompressedOopscanbesetwiththemaxheapsizeallocated
  4. //byergonomics.
  5. if(MaxHeapSize<=max_heap_for_compressed_oops()){
  6. #ifndefCOMPILER1
  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的版本号之间的关系,请参考另一篇笔记: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++代码

  1. voidset_object_alignment(){
  2. //Objectalignment.
  3. assert(is_power_of_2(ObjectAlignmentInBytes),"ObjectAlignmentInBytesmustbepowerof2");
  4. MinObjAlignmentInBytes=ObjectAlignmentInBytes;
  5. assert(MinObjAlignmentInBytes>=HeapWordsPerLong*HeapWordSize,"ObjectAlignmentInBytesvalueistoosmall");
  6. MinObjAlignment=MinObjAlignmentInBytes/HeapWordSize;
  7. assert(MinObjAlignmentInBytes==MinObjAlignment*HeapWordSize,"ObjectAlignmentInBytesvalueisincorrect");
  8. MinObjAlignmentInBytesMask=MinObjAlignmentInBytes-1;
  9. LogMinObjAlignmentInBytes=exact_log2(ObjectAlignmentInBytes);
  10. LogMinObjAlignment=LogMinObjAlignmentInBytes-LogHeapWordSize;
  11. //Oopencodingheapmax
  12. OopEncodingHeapMax=(uint64_t(max_juint)+1)<<LogMinObjAlignmentInBytes;
  13. }
  14. inlineuintxmax_heap_for_compressed_oops(){
  15. //Avoidsignflip.
  16. if(OopEncodingHeapMax<MaxPermSize+os::vm_page_size()){
  17. return0;
  18. }
  19. LP64_ONLY(returnOopEncodingHeapMax-MaxPermSize-os::vm_page_size());
  20. NOT_LP64(ShouldNotReachHere();return0);
  21. }

(注:其中 (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++代码

  1. 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功能。

【编辑推荐】

  1. Java 7将于明年7月28日正式发布面向开发者
  2. Java 7,一个技术标准的商业咒语
  3. Java 7 未按时发布 计划再次延期
  4. Oracle和JCP成员之间的Java战争一触即发
  5. IBM加入OpenJDK 将联手Oracle发展Java技术