jvm参数解析(含调优过程)

前阵       对底层账单系统进行了压测调优,调优的最后一步--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调优路漫漫,吾将继续求索。

时间: 2024-12-17 20:50:15

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

JVM原理讲解和调优

一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. Java语言的一个非常重要的特点就是与平台的无关性.而使用Java虚拟机是实现这一特点的关键.一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码.而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译.Java语言使用Java虚拟机屏蔽了与具体平台相关的信息

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

记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的,但是客户反应说CPU占用很高,经常达到80%~90% 我检查了任务管理器,确实是SQLSERVER占的CPU 而服务器的内存是16G内存,只占用了7G+ 客户的环境: Windows2008R2 SQLSERVER2005 SP3 64位 企业版 服务器内存:16G CPU:8核 RDS:阿里云主机

一次jvm调优过程

jvm调优实战 前端时间把公司的一个分布式定时调度的系统弄上了容器云,部署在kubernetes,在容器运行的动不动就出现问题,特别容易jvm溢出,导致程序不可用,终端无法进入,日志一直在刷错误,kubernetes也没有将该容器自动重启.业务方基本每天都在反馈task不稳定,后续就协助接手看了下,先主要讲下该程序的架构吧. 该程序task主要分为三个模块: console进行一些cron的配置(表达式.任务名称.任务组等): schedule主要从数据库中读取配置然后装载到quartz再然后进

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

一些不得不说的概念 JVM JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回收堆和一个存储方法域. JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行.是运行java应用最底层部分. JDK(Java Development kit) 整个Java的核心,包括了Java运行环境(

调优过程

性能调优 1 百胜表规范 USE ERP_DW GO /* 功能说明: 创建[区域]维度表 修改说明: Create by LY on 2011-09-07 */ IF EXISTS (SELECT 1 FROM SYSOBJECTS WHERE id = OBJECT_ID('Dim_Area') AND type = 'U') BEGIN DROP TABLE Dim_Area END GO CREATE TABLE [dbo].[Dim_Area] ( AreaCode VARCHAR(2

JVM性能分析和调优方向

1)合理配置参数 jvm内存=堆内存+非堆内存 堆内存=新生代+年老代 新生代=1个Eden区+2个survivo区 非堆内存=持久代+代码缓存 -server:服务器模式,该参数放置在配置项的首位置 -Xms:堆的初始大小,单位MB 配置-Xms与-Xmx一致,为可用内存的80% -XmX:堆的最大大小,单位MB -Xmn:新生代的初始大小,单位MB 为堆大小的3/8 当业务中有数据量很大的文件需要导出时,需要调整以下2个参数的值,可避免出现OOM -XX:PermSize:持久代的初始大小,

JVM原理和性能调优

JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境. 1.创建JVM装载环境和配置 2.装载JVM.dll 3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例 4.调用JNIEnv实例装载并处理class类. 在我们运行和调试Java程序的时候,经常会提到一个JVM的概念.JVM是Java程序运行的环境,但是他同时一个操作系统的一个应用程序一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间. 首先来说

JVM堆设置及调优

1.JVM堆设置 -Xmx3550m 设置JVM最大堆内存 为3550M. -Xms3550m 设置JVM初始堆内存 为3550M.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存. -Xss128k 设置每个线程的栈大小.JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K.应当根据应用的线程所需内存大小进行调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右. -Xm

一个简单web系统的接口性能分析及调优过程

在测试一个简单系统接口性能压力时,压到一定数量,程序总是崩溃,查看相关机器相关数据时,CPU.内存.IO占用均不高,问题自然出现在其它地方先介绍下系统部件架构 Resin版本为:[[email protected] lib]# java -classpath ./resin.jar com.caucho.VersionResin-3.2.1 (built Fri, 17 Oct 2008 04:11:01 PDT)Copyright(c) 1998-2008 Caucho Technology.