测试代码如下:

  @Test
public void testPrintGcDetail(){
HashMap<String, List> gcMap = new HashMap<>(999999);
for(int i=0;i<999999;i++){
List<String> gcList = new LinkedList<String>();
gcMap.put(String.valueOf(i),gcList);
}
System.out.println("over");
}

VM options: -Xmx10m -Xms5m -XX:+PrintGCDetails   (注意空格)

-Xmx10m -Xms5m:最大分配堆空间为10m,最小分配堆空间为5m

-XX:+PrintGCDetails: 打印GC详细信息

测试运行结果:

结果:GC(Allocation Failure): minior GC 尝试分配失败,一共尝试了11次;

Full GC (Ergonomics):full GC 全局GC,前面几次正常gc回收,最后回收太频繁了,导致了不给回收了;

最后打印了详细的堆空间占用信息:

YoungGen 总共 2048k(2m)空间,ParOldGen 总共4096k(4m)空间   Metaspace 总共 5447k(5.5M)

YounGen 区域内 eden:from = 1:1 官方默认是 8:1(官方认为最优)

eden 区使用率 96% parOldGen 使用率 30%

调整Xms 到 10m ,使xmx和xms一样大,观察打印结果

对比发现,PSYounGen 区域总空间大小没有改变,而ParOldGen 分配了更多的空间至 7168k

而且实际运行中发现,第二次gc程序报错的时间比第一次要迟(第一次运行了0.873s   第二次运行了1.344s),说明xms的设置过小,导致gc一直在做。

官方给的解释:

Exception in thread thread_name: java.lang.OutOfMemoryError: GC Overhead limit exceeded
Cause: The detail message "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress. After a garbage collection, if the Java process is spending more than approximately 98% of its time doing garbage collection and if it is recovering less than 2% of the heap and has been doing so far the last 5 (compile time constant) consecutive garbage collections, then a java.lang.OutOfMemoryError is thrown. This exception is typically thrown because the amount of live data barely fits into the Java heap having little free space for new allocations.
Action: Increase the heap size. The java.lang.OutOfMemoryError exception for GC Overhead limit exceeded can be turned off with the command line flag -XX:-UseGCOverheadLimit.

VM花费了98%的时间进行垃圾回收,而只得到2%可用的内存,这样是不被允许的,除非加上 -XX:-UseGCOverheadLimit

然后我就区加了这个参数,果然。。。成功地报了堆内存溢出的错误

增加

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=导出的路径   来查看 详细信息,再次运行代码,会生成hprof文件,需要用到mat工具来查询详细信息


最终调整: -Xmx200m -Xms100m -XX:+PrintGCDetails

从图上可以看,正常走完了程序,然后看明细数据:

PSYoungGen  55296k,eden 512000k,from 4096k      eden:from = 12.5

根据占用比计算,一共花费了 46173k+87447k=133620k(约130m) 堆空间,5385k元空间(jdk1.8以后的永久代不在堆内,而转移到直接内存中了)

总结:在设置堆空间时候,xms不要设置太小,不然会一直gc gc gc(即使你的xmx设置的足够大),导致程序出错。当然xmx也不能太小。

JVM 调优测试 之 故意分配小的堆空间,观察gc回收打印的内容的更多相关文章

  1. 深入理解JAVA虚拟机(内存模型+GC算法+JVM调优)

    目录 1.Java虚拟机内存模型 1.1 程序计数器 1.2 Java虚拟机栈 局部变量 1.3 本地方法栈 1.4 Java堆 1.5 方法区(永久区.元空间) 附图 2.JVM内存分配参数 2.1 ...

  2. JVM调优(一)

    JVM调优的主要过程有: 确定堆内存大小(-Xmx, -Xms).合理分配新生代和老生代(-XX:NewRation, -Xmn, -XX:SurvivorRatio).确定永久区大小: -XX:Pe ...

  3. jvm系列(六):jvm调优-从eclipse开始

    jvm调优-从eclipse开始 概述 什么是jvm调优呢?jvm调优就是根据gc日志分析jvm内存分配.回收的情况来调整各区域内存比例或者gc回收的策略:更深一层就是根据dump出来的内存结构和线程 ...

  4. JVM调优浅谈

    1.数据类型 java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:它代表的值就是数值本身,而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本 ...

  5. JVM调优总结 + jstat 分析(转)

    [转] JVM调优总结 + jstat 分析 JVM调优总结 + jstat 分析 jstat -gccause pid 1 每格1毫秒输出结果jstat -gccause pid 2000 每格2秒 ...

  6. JVM调优实战

      JVM调优实战 文档修订记录 版本 日期 撰写人 审核人 批准人 变更摘要 & 修订位置                                                   ...

  7. 老李分享:JVM调优

    老李分享:JVM调优   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨 ...

  8. java虚拟机学习-JVM调优总结-调优方法(12)

    JVM调优工具 Jconsole,jProfile,VisualVM Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用.对垃圾回收算法有很详细的跟踪.详细说明参考这里 ...

  9. JVM调优(二)经验参数设置

    调优设置具体解析 堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5 ...

随机推荐

  1. 虎符ctf-MISC-奇怪的组织(看完官方题解,找到了)

    一道取证题,一整场比赛,基本就死磕了这一题 写的很乱,因为当时的思维就是那么乱,完全没有注意到出题人的提示, 还没做出来,没有找到关键key 那个人的real name 文档:虎符.note链接:ht ...

  2. 1-JVM基础

    1-JVM基础 java源码文件,通过javac 转换成class文件. 找到.java文件 词法分析器 tokens流 语法分析器 语义分析器 字节码生成器 转成.class文件 装载 根据全限定路 ...

  3. tensorflow1.0 lstm学习曲线

    import tensorflow as tf import numpy as np import matplotlib.pyplot as plt BATCH_START = 0 TIME_STEP ...

  4. Redis学习与应用-位图

    什么是位图 位图bitmap是通过一个bit来表示某个元素对应的值或者状态,是由一组bit位组成,每个bit位对应0和1两个状态,虽然内部还是采用string类型进行存储,但是redis提供了直接操作 ...

  5. Mac安装Nginx、Mysql、PHP、Redis

    安装xcode命令行工具的命令 xcode-select --install   安装homebrew: ruby -e "$(curl -fsSL https://raw.githubus ...

  6. 创建线程的方式三:实现Callable接口-----JDK5.0 新增

    package com.yhqtv.java2; /* * 创建线程的方式三:实现Callable接口-----JDK5.0 新增 * * 如何理解实现Callable接口的方式创建多线程比实现Run ...

  7. 【集群实战】NFS服务常见故障排查和解决方法

    NFS,全名叫Network File System,中文叫网络文件系统,是Linux.UNIX系统的分布式文件系统的一个组成部分,可实现在不同网络上共享远程文件系统. NFS由Sun公司开发,目前已 ...

  8. 【Linux常见命令】find命令

    find - search for files in a directory hierarchy find命令用来在指定目录下查找文件. 任何位于参数之前的字符串都将被视为欲查找的目录名. 如果使用该 ...

  9. 澳大利亚公共服务部门神速完成Win10部署:4个月完成44000台设备升级

    不到一年时间,澳大利亚公共服务部门已经完成Win10系统部署升级,涉及到全部的35000名员工.在2015年,澳大利亚公共服务部门IT员工告知微软,需要更创新的方式远程为居民提供服务,并且效率要更快. ...

  10. stl的stack在开发中的应用

    栈有后进先出特点,我们可以用它来暂时保存数据,在画板开发中,我用到了栈来保存用户的每一步操作,当用户点击撤销时可以把图像从栈里面取出,然后恢复.浏览器的前进和后退也是这个原理,只是它保存的是网页罢了. ...