系统在灰度环境上变更时发现JVM启动报错,详细检查JVM配置参数,发现新境了如下配置:

-XX:+UseAdaptiveSizePolicy和-XX:+UseConcMarkSweepGC

初步猜想是JVM参数配置的问题,于是通过jmap -heap查看系统堆栈使用情况,如下:

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

从打印的堆栈信息上看已发现异常

一、JVM分析

1、源码查看

分析jdk的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不能获取数据原因

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";
……

二、问题产生原因

目前确认是jvm的bug,初步确认版本为1.6_u30以上,包括1.7都存在该问题.jdk6.30以下版本还未确认(使用1.6_u25版本后,目前还没有复现问题)---1.6.30以上到1.7的全部版本已经确认有该问题,jdk8修复,其他版本待验证

简要原因分析请参见: 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对象失败,最终导致产生显示异常。

三、解决办法

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

UseAdaptiveSizePolicy与CMS垃圾回收同时使用导致的JVM报错的更多相关文章

  1. CMS垃圾回收机制

    详解CMS垃圾回收机制   原创不易,未经允许,不得转载~~~ 什么是CMS? Concurrent Mark Sweep. 看名字就知道,CMS是一款并发.使用标记-清除算法的gc. CMS是针对老 ...

  2. CMS 垃圾回收日志

    CMS 垃圾回收日志 https://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs http://www.blogjava.net/D ...

  3. CMS垃圾回收与G1垃圾回收

    CMS垃圾回收与G1垃圾回收的比较请参见:http://colobu.com/2015/04/14/G1-Getting-Started/

  4. 图解 CMS 垃圾回收机制原理,-阿里面试题

    最近在整理JVM相关的PPT,把CMS算法又过了一遍,每次阅读源码都能多了解一点,继续坚持. 什么是CMS CMS全称 ConcurrentMarkSweep,是一款并发的.使用标记-清除算法的垃圾回 ...

  5. 图解 CMS 垃圾回收机制,你值得拥有(转 强烈推荐)

          首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 - 导航条 - 首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源     ...

  6. Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法

    Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法 可能是误删文件导致在使用rman备份时候出现以下提示 RMAN-06169: could not read file hea ...

  7. SAP S4HANA 账户组的配置里'Int.Std.Grping'选项没勾选导致ABAP程序报错

    SAP S4HANA 账户组的配置里'Int.Std.Grping'选项没勾选导致ABAP程序报错 BP,试图创建一个新的vendor code, 角色是ZGM001, Grouping是G001, ...

  8. 分析https网页加载http资源导致的页面报错原因及其解决方案

    https网页加载http资源导致的页面报错及解决方案 https是当下的网站的主流趋势,甚至像苹果这样的大公司,则完全要求用户必须使用https地址. 然而对于以前http链接来说,我们往往就存在一 ...

  9. 详解CMS垃圾回收机制

    原创不易,未经允许,不得转载~~~ 什么是CMS? Concurrent Mark Sweep. 看名字就知道,CMS是一款并发.使用标记-清除算法的gc. CMS是针对老年代进行回收的GC. CMS ...

随机推荐

  1. Hibernate之管理session与批处理

    1. Hibernate 自身提供了三种管理Session对象的方法 –Session对象的生命周期与本地线程绑定 –Session 对象的生命周期与JTA事务绑定 –Hibernate 委托程序管理 ...

  2. Java缓存学习之一:缓存

    一.缓存 1.什么是缓存? 缓存是硬件,是CPU中的组件,CPU存取数据的速度非常的快,一秒钟能够存取.处理十亿条指令和数据(术语:CPU主频1G),而内存就慢很多,快的内存能够达到几十兆就不错了,可 ...

  3. codeforces 630F Selection of Personnel(组合数)

    F. Selection of Personnel time limit per test 0.5 seconds memory limit per test 64 megabytes input s ...

  4. ASP.NET(C#)中的try catch异常处理机制

    在开发一个Umbraco平台系统的过程中,遇到了问题. 写的代码如下 fileUrl = MediaHelper.GetMediaUrl(Convert.ToInt32(publishedConten ...

  5. 转载 C#结构体(struct)和类(class)的区别

    转载原地址: http://dotnet.9sssd.com/csbase/art/8 C#结构体和类的区别问题:在C#编程语言中,类属于引用类型的数据类型,结构体属于值类型的数据类型,这两种数据类型 ...

  6. HDU 4597 Play Game (DP,记忆化搜索,博弈)

    题意:Alice和Bob玩一个游戏,有两个长度为N的正整数数字序列,每次他们两个,只能从其中一个序列,选择两端中的一个拿走.他们都希望可以拿到尽量大的数字之和, 并且他们都足够聪明,每次都选择最优策略 ...

  7. C#全角半角转换函数

    Code#region 全角半角转换 /// <summary> /// 转全角的函数(SBC case) /// </summary> /// <param name= ...

  8. .NET Reflector插件FileDisassembler还原源码

    NET Reflector,它是一个类浏览器和反编译器,可以分析程序集并向您展示它的所有秘密..NET 框架向全世界引入了可用来分析任何基于 .NET 的代码(无论它是单个类还是完整的程序集)的反射概 ...

  9. OpenNebula 创建虚拟机失败(未解决)

    Tue Jul :: [ReM][D]: Req: UID: AclInfo invoked Tue Jul :: [ReM][D]: Req: UID: AclInfo result SUCCESS ...

  10. sgu - 274 - Spam-filter

    题意:判断一个字符串是不是有效的邮件地址. 题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=274 ——>>照着题目做. ...