注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

断尘居

温柔的男人像海洋。

 
 
 
 
 

日志

 
 

UseAdaptiveSizePolicy与CMS垃圾回收同时使用的深层分析  

2014-11-11 14:27:40|  分类: JVM/ HotSpot |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
O. 实际应用可能产生问题的条件:
1. JMX获取内存信息
2. jvm启动参数同时使用-XX:+UseAdaptiveSizePolicy和-XX:+UseConcMarkSweepGC
3. 使用sun jdk(1.6.30以上到1.7的全部版本已经确认有该问题,jdk8修复,其他版本待验证)


应用注意点:
UseAdaptiveSizePolicy,以及MaxGCPauseMillis 都是给Parallel GC(一般server的jvm模式,比如64位windows和linux操作系统,默认采用的GC方式,更多版本可以参考官方文档,也可以通过java -version 查看是不是server模式)用的,不建议用于CMS。

以分析HBase的一次问题(CDH提供的官方版本的jvm配置中,将并行GC,CMS和这些参数放在一起导致了该问题,因为开始没有怀疑到这点,所以反而深入了解了具体原因)为例:
一、异常:
    1)程序异常  2013-11-11 14:01:21,159 FATAL org.apache.hadoop.hbase.regionserver.HRegionServer: ABORTING region server SERVER_SERVER: Unhandled exception: committed = 10729504768 should be < max = 10379526144
              java.lang.IllegalArgumentException: committed = 10729504768 should be < max = 10379526144
        at java.lang.management.MemoryUsage.<init>(MemoryUsage.java:145)
        at sun.management.MemoryImpl.getMemoryUsage0(Native Method)
        at sun.management.MemoryImpl.getHeapMemoryUsage(MemoryImpl.java:61)
        at org.apache.hadoop.hbase.regionserver.HRegionServer.buildServerLoad(HRegionServer.java:932)
        at org.apache.hadoop.hbase.regionserver.HRegionServer.tryRegionServerReport(HRegionServer.java:906)
        at org.apache.hadoop.hbase.regionserver.HRegionServer.run(HRegionServer.java:770)
        at java.lang.Thread.run(Thread.java:662)
2013-11-11 14:01:21,160 FATAL org.apache.hadoop.hbase.regionserver.HRegionServer: RegionServer abort: loaded coprocessors are: []


     2) jmap -heap 结果:(集群所有节点上都这样,因此猜想jvm参数配置)
Debugger attached successfully.
Server compiler detected.
JVM version is 20.5-b03

using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 10737418240 (10240.0MB)
   NewSize          = 2147483648 (2048.0MB)
   MaxNewSize       = 2147483648 (2048.0MB)
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 4
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 134217728 (128.0MB)

Heap Usage:
unknown generation type:
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   NaN% used
unknown generation type:
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   NaN% used
Perm Generation:
   capacity = 60878848 (58.05859375MB)
   used     = 37927152 (36.17015075683594MB)
   free     = 22951696 (21.888442993164062MB)
   62.29939173619054% used



二、结果:在HBase中,导致regionserver设置状态abortRequest,于是HRegionServer.run线程退出,其他线程正常服务(jstack对比看出)。abortRequest状态下,regionserver不对外提供任何数据请求服务,所以无法服务。



三、原因
       1)程序异常:确认是jvm的bug,初步确认版本为1.6_u30以上,包括1.7都存在该问题(无法登陆官方bugs.sun.com确认),jdk6.30以下版本还未确认(使用1.6_u25版本后,目前还没有复现问题)。
         原因简要分析:(http://blog.csdn.net/axman/article/details/8667351
         在使用cms算法下,如果开启参数UseAdaptiveSizePolicy,则每次minor gc后会重新计算eden,from和to的大小,计算过程依据的是gc过程统计的一些数据,计算后的eden+from+to不会超过Xmx,同时from和to一般是不相等(初始化的时候from和to是相等的)。主要问题在于计算完后,如果eden变大,ContiguousSpacePool里面的max_eden_size并没有被更新,还是最开始时候的值,这样导致jvm在通过call_special调用java.lang.management. MemoryUsage的构造函数的时候会产生exception,产生exception的原因是eden的committed 大于 eden的max_size,导致返回java.lang.management. MemoryUsage对象失败,最终导致产生显示异常。

sun的jdk到目前并没有修改该bug。



          JVM实现分析management.cpp代码中,在计算堆内存区大小的时候,对commit都累加了的,但是在max_size没有定义(无效,从MemoryPool获取)的情况下,total_max没有累加,导致commited比max大。修复后的代码见:http://hg.openjdk.java.net/hsx/hsx25/hotspot/file/a70566600baf/src/share/vm/services/management.cpp的方法JVM_ENTRY中。  对比:
原来只处理:
if (!has_undefined_max_size) {
  total_max += u.max_size();
}

修复该问题的方式:增加代码处理没有定义init和max的情况
if (has_undefined_init_size) {
     total_init = (size_t)-1;
  }
if (has_undefined_max_size) {
      total_max = (size_t)-1;
  }

   
      2) jmap出现不能获取的原因:(UseAdaptiveSizePolicy + CMS同时使用会出现) (该状况源码: sun/jvm/hotspot/memory/GenerationFactory.java ): 
try {
     return (Generation) ctor.instantiateWrapperFor(addr);
} catch (WrongTypeException e) {
     return new Generation(addr) {
     public String name() {
     return "unknown generation type";
……


四、解决办法:
解决办法:可以先设置 –XX:-UseAdaptiveSizePolicy来workaround。
JDK的版本:sun jdk出问题后的版本目前看是只有jdk8修复。openjdk是hs25修复。


五、参考资料

相关资料:https://bugs.openjdk.java.net/browse/JDK-8020530 openJDK在jdk7修复的记录
Release Notes: http://www.softpedia.com/progCha ... hangelog-82226.html SUN JDK没有修复的记录(jdk8已经修复了)
http://permalink.gmane.org/gmane.comp.jakarta.tomcat.user/220000 



===============================================
原文:http://blog.csdn.net/doliu6/article/details/15500627

  评论这张
 
阅读(564)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017