前阵       对底层账单系统进行了压测调优,调优的最后一步--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. 日常API之百度翻译

    百度翻译是什么,可以吃吗?相信很多人都熟悉,它是我们生活中必不可少的一只东东. 但是,百度翻译开发平台只有每月只能翻译200万个字符,多出的要按照49.00/百万字符来算.对于我酱紫的乞丐程序员来说, ...

  2. Java程序设计模式系列之适配器模式

    理解适配器设计模式需要从生活中的场景进行联系,在生活当中有那些东西能够称为适配器呢?从字面上理解,"适配"的意思就是让一个东西和另一个东西配对,能够让他们一起工作,比如大家用的笔记 ...

  3. MySQL(一)--基本语法与常用语句

    将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合称为数据库(Database,DB). 将姓名.住址.电话号码.邮箱地址.爱好和家庭构成等数据保存到数据库中,就可以随时迅速获取想要的 ...

  4. setTimeout与setInterval参数之String

    今天无意中给某网友解答了一些setTimeout的问题,发现一个有趣的东西. 以前我总认为setTimeout的第一个参数只能function,后面发现string也能执行.那问题来了,String做 ...

  5. Linux的同步访问技术

    1.中断屏蔽: 单CPU范围内避免竞态的一种简单方法:在进入临界区之前屏蔽系统的中断.中断屏蔽将使得中断与进程之间的并发不再发生,而且Linux内核的进程调度等操作都依赖中断来实现,内核抢占式进程之间 ...

  6. django-将数据库数据转换成JSON格式(ORM和SQL两种情况)

    最近打算搞一个自动化运维平台,所以在看Django的知识. 在实际项目开发中,遇到一个小问题:前后端发生数据交互主流采用的是JSON.前端传数据到服务器端比较简单,稍微麻烦的是服务器端传JSON到前端 ...

  7. Linux配置LNMP环境(一)配置Nginx

    注意:配置版本nginx-1.12.0,使用虚拟机安装linux.教程中的下载地址可能有变化.注意(在您看本教程之前首先需要对linux的基本操作熟悉) 1.  先cd到/usr/local/src ...

  8. win32SDK的hello,world程序(二)

    接上篇,原生的控件都不太好看,所以决定自己画一个,稍微处理下消息就能用了.不过,美化这东西是需要天赋的.即使技术再好,没有对UI布局调整和良好的审美能力,做出来的东西还是很挫. 主要把消息逻辑和画的过 ...

  9. Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法

    当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...

  10. memcache 细究(一)

    memcached是高性能的分布式的内存缓存服务器.由国外社区网站LIVEJOURNAL的开发团队开发. 使用目的: 通过缓存数据库查询结果,减少数据库的访问次数,以提高动态web应用的速度.提高可扩 ...