前阵       对底层账单系统进行了压测调优,调优的最后一步--jvm启动参数中,减小了线程的堆栈空间:-XX:ThreadStackSize=256K,缩减至原来的四分之一,效果明显,不过并没有调试其他内存空间及gc相关参数。这次有机会在实际压测中,调优这一部分内容,笔者以cms收集器为例,将有、无调优配置情况下的压测结果进行对比,来分析各项调用参数的意义及效果。


准备工作:

1.调用查询接口的测试jar包,作为dubbo-consumer,依赖了查询服务的api,测试module基于maven开发,执行maven clean package即可通过编译得到jar包,本次查询api使用账户查询接口getUserAccount

2.JMeter:Apache组织开发的基于Java的压力测试工具,添加测试计划,线程组容量均为200

方案:

无限次请求查询接口(保证任意时刻并发量相同),观察Error%为0,当请求平稳进行时的tps,为该接口吞吐量

实施:

1.jvm中只配置打印gc日志等监控参数

-XX:+PrintGCDetails:打印gc日志详细信息

-XX:+PrintGCTimeStamps:打印gc发生时相对jvm启动的时间戳,(后来加入了PrintGCDateStamps,打印gc发生的日期)

-Xloggc:设置gc日志的生成位置

压测聚合报告

压测数据稳定后,我们观察到200线程并发压力下,tps可达到1200+,99%Line600ms左右,我们观察一下gc日志

这里截取了一次minor gc的数据,两次gc发生间隔很短(最短不到1s就发生第二次minor gc),系统默认为新生代只分配了100到200MB左右空间,老年代也就是200到300MB左右,可以看出默认分配的空间并不大,并且由于新生代容量非常小,一直在频繁发生gc。jvm默认采用PSYoungGen-并行收集器来回收新生代空间。

2.jvm中加入cms收集器,并手动规划jvm空间分配

-Xms4096M:堆容量初始值

-Xmx4096M:堆容量最大值

-Xmn1024M:新生代容量,所以老年代容量 = 堆容量 - 新生代容量 = 3072M

-Xss256K:线程堆栈空间大小

-XX:MaxDirectMemorySize:Direct Buffer Memory大小

-Djava.awt.headless=true:使用缺少外设的系统配置模式

-Dfile.encoding=UTF-8:设置编码规范

jmx配置用于远程管理

-XX:+HeapDumpOutOfMemoryError:当出现OOM时,打印堆快照

-XX:HeapDumpPath:堆快照打印路径,建议文件后缀设为hprof,可被MAT识别

-XX:+DisableExplicitGC:关闭System.gc()

-XX:SurvivorRatio=1:Eden区与Survivor区的大小比值

-XX:+UserConcMarkSweepGC:使用CMS收集器

-XX:+UserParNewGC:新生代使用ParNew收集器

-XX:+CMSParallelRemarkEnabled:降低标记停顿

-XX+UseCMSCompactAtFullCollection:在full gc的时候,对年老代的压缩

-XX:CMSFullGCsBeforeCompaction=0:full gc后不压缩老年代内存空间

-XX:LargePageSizeInBytes:内存页的大小

-XX:+UseFastAccessorMethods:原始类型的快速优化

-XX:+UseCMSInitiatingOccupancyOnly:使用手动定义初始化定义开始CMS收集,禁止hostspot自行触发CMS GC

-XX:CMSInitiatingOccupancyFraction=80:老年代使用80%后开始CMS收集

-XX:SoftRefLRUPolicyMSPerMB=0:每兆堆空闲空间中SoftReference的存活时间为0秒

以上这些配置我们重点关注jvm空间分配相关参数和收集器相关参数,首先扩大了堆空间大小至4G,新生代1G,老年代3G,直观上系统可以承载更多实例的创建,但是同样也可能造成因对象引用导致的寻址时间增加。另外,手动配置了使用CMS收集器回收老年代,CMS是一种以最短停顿时间为目标的收集器,使用CMS并不能达到GC效率最高,但由于其拥有并发线程进行标记工作,所以尽可能地降低了GC时服务的停顿时间。而为了保证应用线程不停顿,系统需要更多的CPU资源。总得来说,CMS回收器减少了回收的停顿时间,但是降低了堆空间的利用率,也降低了吞吐量,所以使用该收集器的前提是应用程序对停顿比较敏感,并且有许多生存周期长的对象。我们在此处使用该收集器主要用来观察手动配置后与默认配置相比有哪些优劣。压测结果如下

我们发现这种情况下吞吐量有小幅度提高,并且响应时间降低,那么jvm起了哪些作用呢,我们看一下gc日志

eden、s1、s2容量被新生代均分为3份,两个gc间隔时间为2s左右,已进行了2次full gc,其余时间一直在执行minor gc。两张图结合分析,我们发现随着新生代容量的扩大,jvm创建实例能力略有提高,同样200个线程的并发压力,同一时间可以承受更多的请求,那是不是新生代容量越大吞吐量就越高呢,笔者后来将新生代内存调至3G,吞吐量不增反降,说明其二者并不是线性相关。我们此时可以确定的是:jvm内存容量要适当增大,并且内存分配比例要尽可能符合jvm对对象的实际创建情况。


总结:

jvm参数是灵活使用jvm的关键,我们在使用时需要谨慎添加,当然如果搭配的好,至少在系统内部服务层面,性能会有客观的提升。但这也是想表达的另一个观点,如何配置jvm内存空间,选择哪些gc收集器组合,并没有绝对的标准,绝对的好与不好,都是在多次的权衡、搭配下,产生对你所运行的服务一个相对好的效果。jvm调优路漫漫,吾将继续求索。

jvm参数解析(含调优过程)的更多相关文章

  1. JVM原理讲解和调优

    一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...

  2. JVM基本配置与调优

    JVM基本配置与调优 JVM调优,一般都是针对堆内存配置调优. 如图:堆内存分新生代和老年代,新生代又划分为eden区.from区.to区. 一.区域释义 JVM内存模型,堆内存代划分为新生代和老年代 ...

  3. JVM底层原理及调优之笔记一

    JVM底层原理及调优 1.java虚拟机内存模型(JVM内存模型) 1.堆(-Xms -Xmx -Xmn) java堆,也称为GC堆,是JVM中所管理的内存中最大的一块内存区域,是线程共享的,在JVM ...

  4. 记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)

    记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的, ...

  5. (转)JVM原理讲解和调优

    背景:jvm实际调优在面试时候经常被问到,所以有必要认真总结一番. 转自:JVM原理讲解和调优 四.JVM内存调优 首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存 ...

  6. java中对JVM的深度解析、调优工具、垃圾回收

    jdk自带的JVM调优工具 jvm监控分析工具一般分为两类,一种是jdk自带的工具,一种是第三方的分析工具.jdk自带工具一般在jdk bin目录下面,以exe的形式直接点击就可以使用,其中包含分析工 ...

  7. 一次jvm调优过程

    jvm调优实战 前端时间把公司的一个分布式定时调度的系统弄上了容器云,部署在kubernetes,在容器运行的动不动就出现问题,特别容易jvm溢出,导致程序不可用,终端无法进入,日志一直在刷错误,ku ...

  8. 【JVM专题】JVM从概述到调优图文详解,含思维脑图深度剖析!

    JVM概述 JVM 是一种用于计算机设备的规范,它是一个虚构的计算机的软件实现,简单的说,JVM 是运行 byte code 字节码程序的一个容器. 它有一个解释器组件,可以实现 JAVA 字节码和计 ...

  9. Jvm原理剖析与调优之内存结构

    一些不得不说的概念 JVM JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机包括一套字节码指令集.一组寄存器.一个栈.一个 ...

随机推荐

  1. JAVA基础——Arrays工具类十大常用方法

    Arrays工具类十大常用方法 原文链接:http://blog.csdn.net/renfufei/article/details/16829457 0. 声明数组 String[] aArray ...

  2. Example008关闭IE窗口时,不弹出询问对话框

    <!-- 实例008关闭IE主窗口时,不弹出询问对话框 --> <meta charset="UTF-8"> <a href="#" ...

  3. 使用asp.net mvc部分视图渲染html

    为了提升用户体验,一般我们采用ajax加载数据然后根据数据渲染html,渲染html可以使用前端渲染和服务器端渲染. 前端渲染 使用前端模版引擎或MVC框架,例如underscore.js的templ ...

  4. ASP.NET MVC Autofac依赖注入的一点小心得(包含特性注入)

    前言 IOC的重要性 大家都清楚..便利也都知道..新的ASP.NET Core也大量使用了这种手法.. 一直憋着没写ASP.NET Core的文章..还是怕误导大家.. 今天这篇也不是讲Core的 ...

  5. ansible学习之路

    ansible安装

  6. Angular表单控件需要类型和实际值类型不一致时实现双向绑定

    适用Angular版本为:>=2.本文同样适用于Ionic这类的基于Angular实现的框架. 本文的思路也适用于控件显示的值和实际的值不一样时实现双向绑定. 1. 问题描述 在使用md2的da ...

  7. 关于阻止PROE联网的一些想法!

    前言:商业上使用盗版proe会被官方警告,官方是通过proe软件联网来获取你的ip地址,那他是怎么知道你是商业用途而不是个人(一般不会对个人的盗版行为进行警告)?这不难,应该是通过检测同一ip下有多台 ...

  8. xdu_1165:均值滤波

    题目: Problem A 均值滤波问题描述图像中的噪声在空间上的自相关很低,因此往往可以用均值滤波加以削弱.具体来说,对于每个像素点P(x; y),我们选出所有距P 的Manhattan 距离不超过 ...

  9. 树状数组(瞎bb) [树状数组]

    Copyright:http://www.cnblogs.com/ZYBGMZL/ 树状数组是一个利用一维数组和位运算组成的求解区间问题的高效数据结构,其构造如图所示 首先,我们要用它解决单点修改.区 ...

  10. JavaScript系统学习小结——Object类型、Array类型

    今天学习JavaSript中引用变量中的Object类型和Array类型: 1. Js中大多数引用类型值都是Object类型的实例,Object类型在应用程序中存储和传输数据时,是非常理想的选择: 创 ...