- 浏览: 466912 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
alvin198761:
<div class="quote_title ...
别给12306 辩解了 -
renzhengzhi:
我参与过12306余票查询系统的开发,用户请求被前面3层缓存拦 ...
别给12306 辩解了 -
renzhengzhi:
写的很好。
JAVA线程dump的分析 -
liyonghui160com:
说好的附件呢
分布式服务框架 Zookeeper -- 管理分布式环境中的数据 -
ghpaas:
orbeon作为xforms标准的实现,不论其设计器还是运行时 ...
XForms 1.1 中文翻译—第1章 关于XForms标准
From http://www.ibm.com/developerworks/cn/java/j-lo-optimize-gc/
某个大型项目的 CPU100% 的压力性能测试, 用以检查在系统运行环境不正常的情况下,系统可以运行到何种程度。测试过程是:请求测试的模拟器向系统不断发出大量请求, 系统接受由模拟器发出的请求,然后将请求置于一个任务池中,如果当前有空闲的线程,则该线程会从任务池中取出一个任务进行处理,如果没有空闲的线程,则该任务一直会待在任务池中,直到有空闲的线程来处理它。因此,任务池的队列的长度从某种意义上可以代表整个系统的处理能力,任务池队列的长度用 Q 值来表示,如果 Q 值超出了一定限额,将会有流量控制的线程将超出限额的待处理任务丢弃,以保证系统的稳定性。
整个测试要求得到系统所在服务器的负载达到将近 100% 时,系统的吞吐量,相应时间以及在超负荷下业务请求成功率。
在测试过程中,任务池中累积的任务数起伏很大,正常时累积的任务数很小,但是每隔一段时间会累积大量的任务。由于累积的任务数超出任务池流量控制所定义的限额,所以 每隔一段时间,大量的待处理任务被清除。因此测试结束后得到的在超负荷下业务请求成功率也不是很理想。
一台AIX服务器(4CPU,4GMemory)来部署本Web应用程序;Web应用程序部署在中间件应用服务器上;部署了一个节点(Node),只配置一个应用服务器实例(Instance),没有做 Cluster 部署。
|
检测 WebSphere Application Server 上的 Web Container,EJB Container , ORB Service,数据库连接池等设置均合理,然后怀疑问题的现象是不是与系统 GC 有关。当前 Java Virtual Machine 的配置为:Initial Heap Size:256 , Maximum Heap Size:3072。
为了验证任务池中累积的任务数的大幅度变化和系统 GC 是否存在一定的关系,通过对任务池的累积任务数和系统 GC 进行采样, 将采样后的数据进行分析,用以得出二者的关系。采样时遵循 Nyquist 采样定例:采样频率要大于被采集对象的频率的 2 倍。 否则,采样点很可能每次位于被采集对象的波形的某个点上,从而不能正确反映被采集对象的变化规律。
通过观察,发现任务池的任务数目(以下用 Q 值代替)的变化周期大概是 5 到 6 秒,因此根据 Nyquist 采样定例,采样的时间间隔不能超过 2-3 秒,所以按照每秒来采样。 测试时间是 3 分钟,采样 180 次,系统的当前负载率是 99%。采样图如下所示:
由于系流量控制要求的限额是 450 个任务,也就是任务池中最多能累积 450 个任务,当任务池中累积的任务数超过 450 时,多余的任务会被流量控制直接丢弃,从上图可以看出,系统的Q值在很多时刻都大于 450,因此多次被丢弃任务,从而导致了任务请求成功率不高。
系统 GC 的采样
- 在 WebSphere Administrative Console 上, 点击进入 Servers, 然后 Application servers > server1 > Process Definition > Java Virtual Machine, 在 Configuration 面板上,选上 Verbose garbage collection 选项。
图二 WebSphere Application Server的JVM配置示图
- 进入 <%WebSphere Application Server 的安装目录 %>/profiles/<% 所在的 profiles%>/logs/ <% 所在的 Server%>, 可以看到 native_stderr.log 文件,将其清空
- 在高负载的条件下,进行高压测试 3 分钟
- 将 native_stderr.log 文件拷贝出来,用 GCCollector 工具进行分析,其中 native_stderr.log 文件上记录了系统 GC 的数据。
- 安装 GCCollector 工具:下载完 GCCollector.zip 后,解压缩,将里面 Lib 里的 3 个文件 jfreechart-1.0.0-rc1.jar,jcommon-1.0.0-rc1.jar 和 GCCollector.jar 拷贝至 JRE 的 lib 目录下,然后在命令行控制台上进入JRE的安装目录,而后运行:
java -classpath jfreechart-1.0.0-rc1.jar;jcommon-1.0.0-rc1.jar -jar GCCollector.jar
。接着可以看到 GCCollector 的用户界面,在它的 Parser 菜单中选择 JRE 的版本,而后在 File 菜单中选择并打开刚才拷出的 native_stderr.log 文件。
下图是在高负载情况下,系统在当前配置下的 GC 分析图。
图三 系统的 GC 分析图
由图三可以看出,系统没有内存泄漏的现象,每次 GC 所花的时间为 220ms 左右,从 GCCollector 的 Spreadsheet 可以查到,GC 的时间周期为 5-6 s,每次具体 GC 发生的时间,每次 GC 所花的时间。
- 同样遵循 Nyquist 采样定例,对 GC 进行采样,采样后的数据同任务池中 Q 值的采样数据进行比较和分析,得出两者之间存在着密切的关系。下图为任务池 Q 值和 GC 数据采样分析图,由图中可以看出,每次任务池的 Q 值大幅度增长时,系统刚好发生 GC。二者的时间和周期几乎可以完全匹配。因此可以初步下一个结论,由于系统的 GC,导致了系统在某些时刻不能有足够的能力来处理请求,因此任务池的 Q 值在这些时候会因为任务的大量累积而巨幅涨大,即而超出限额的任务被流控所清除,导致了在超负荷下任务请求成功率不是很理想。
图四 任务池 Q 值和 GC 数据采样分析图
|
|
当前的 GC 发生的频率和每次所花的时间还算正常,但是如果每次 GC 所花的 CPU 时间能减少,就能空出系统更多的能力处理任务池里的任务,用以降低任务池中的任务数,使得 Q 值基本上位于任务池的限额以下,这样可以提高在超负荷下业务请求的总的成功率。
当前 Java Virtual Machine 的配置为:Initial Heap Size:256 , Maximum Heap Size:3072。相对而言, Maximum Heap Size 设的有点偏大。对于不同的应用程序,最优化堆大小的设置都有可能不同。堆设置变大,GC 的频率会降低,应用程序会运行更长的时间后,才会进行 GC,带来的就是每次 GC 也会花更长的时间。从而 GC 调用占用系统更长的时间,使系统没有足够的能力处理请求,使得此刻任务池中的任务累积很多,Q 值很大,形成很高的峰值,超过流量控制的限额,超过限额数的任务被流量控制给直接丢弃,从而导致总的成功率不高。
因此,必须降低堆大小,使得 GC 的频率增大,每次 GC 所花时间降低,从而降低 Q 的峰值,使之位于系统的流量控制的范围之内,从而提高业务请求的总的成功率。
当前的流量控制所允许的峰值是 450,因此我们需要通过试验来验证,堆大小降低到什么值时,Q 值的峰值将低于 450,以保证总的成功率。 同时在峰值低于 450 的条件下,什么样的堆大小设置可以让系统的性能最佳。因为如果堆设置过小,会使得对象可分配空间变小,从而会频繁的使用垃圾收集机制来释放内存空间,而每次垃圾收集,都会耗用一定的系统资源。所以,我们要通过试验和监控数据,设法使的我们所设置的堆大小能够使得我们的程序运行最优化。
通过多次试验,我们得出结论:当 Java Virtual Machine 的配置为:Initial Heap Size:512 , Maximum Heap Size:1024 时,该系统性能最佳。
从 WebSphere Administrative Console上,依次点击 Servers->Application Servers,然后选择需要的 server,接着点击 Process Definition->Java Virtual Machine,而后在那里设置 Initial Heap Size:512 和 Maximum Heap Size:1024。 这时的配置对于该应用系统相对较为合理。这时再次分析 3 分钟内的 GC 的数据,从下图可以看出,GC 的周期缩短了,每 1-2 秒就会发生一次 GC,但是每次 GC 所花费的 CPU 时间降低了,平均 130ms 左右。
相应地,在 JVM 配置改进后,对任务池的 Q 值再进行一次采样,并且和改进前的采样值进行比价,采样图如下图六所示,改进后任务池的 Q 值分布在 50-450 之间,数值的起伏相对改进前要均衡些。不再出现忽然间 Q 值大小涨到 500 以上的情况,基本在流控的限制范围之类,进而提高了在超负荷下业务请求的总的成功率。
|
|
通过本文,我们可以看到系统 JVM 的配置和系统的性能有着比较大的关系,特别当系统的处理能力成某种变化趋势时,要考虑到系统 GC 对系统性能的影响,为了找到两者的关系,可以通过采样,图形比较来进行分析。如果发现二者之间有密切的联系,可以考虑对 JVM 的配置进行优化,比如:对最优化堆的大小进行调整。
对于不同的应用程序,最优化堆大小的设置都有可能不同。如果堆设置较大,可能导致 GC 的次数变少,但每次 GC 所花的时间很长,从而导致系统的处理能力抖动很大。此外如果堆设置过大,会占用过多的内存,使内存资源耗尽,从而会频繁的进行 IO 操作来使用虚拟内存。 如果堆设置较小,可能导致 GC 变的频繁,但每次 GC 所花的时间不会太长,每次 GC 对系统的性能影响相对也会小些。但是如果堆设置过小, 会使得对象可分配空间变小,从而会频繁的 GC 来释放内存空间,而每次 GC,都会耗用一定的系统资源。因此,要通过试验和监控数据,设法使的我们所设置的堆大小能够使得系统运行最优化。
学习
-
Java 理论与实践: JVM 1.4.1 中的垃圾收集(developerWorks,2003 年 12 月,Brian Goetz):探讨 JVM 1.4.1 是如何实际处理垃圾收集的。
-
关注性能: 调优垃圾收集(developerWorks,2004 年 7 月,Jack Shirazi , Kirk Pepperdine):介绍如何将 100 MB 的垃圾打包成 50 MB 的包。
-
WebSphere Application Server 信息中心:更多产品信息。
- 在 IBM developerWorks Java 技术专区 中可以找到数百篇有关 Java 编程各个方面的文章。
发表评论
-
.NET开源核心运行时,且行且珍惜
2014-12-25 15:39 1823背景 2014年11月12日,ASP.NET之父、微软云 ... -
常用 Java Profiling 工具的分析与比较
2010-08-15 22:04 1134相对于静态代码分析,Profiling 是通过收集程序运行 ... -
监控系统内存
2010-07-01 14:15 1172public CollectorThread(int seco ... -
Debugging the JNI
2010-06-18 14:03 961If you think you have a JNI p ... -
JNI原理2
2010-06-18 13:31 156615.2 调用C程序 JNI规范 ... -
JNI原理1
2010-06-18 13:14 1231在某些Java的忠实支持者眼中,JNI(Java Nati ... -
JNI的crash终于搞定<转>
2010-06-18 13:08 1654今天终于搞定困扰我一周的一个问题了。我们的算法通过jni封装, ... -
java的volatile是什么意思
2010-04-20 15:39 1299我们知道,在Java中设置变量值的操作,除了long和d ... -
Concurrent kickoff
2010-04-19 15:55 1340This example shows you the ... -
IBM JDK和sun jdk区别
2010-04-19 15:52 2503在IBM的虚拟机官方指导文档中明确指出,禁止将虚拟机的最大 ... -
如何在IBM JDK 1.4.2的环境中避免Java堆空间的碎片问题
2010-04-19 15:48 831用户在使用WebSphere Applic ... -
Concurrent mark
2010-04-15 19:39 984Concurrent mark gives reduced ... -
Java 技术,IBM 风格: 垃圾收集策略,第 1 部分
2010-04-15 16:51 923可以使用 4 种不同的策略配置 IBM Developer ... -
Java 网页浏览器组件介绍
2010-04-12 23:44 1455前言 在使用 Java 开发客户端程序时,有时会需要在界 ... -
利用 Java dump 进行 JVM 故障诊断
2010-04-06 16:54 1920引言 对于大型 java 应用程序来说,再精细的测试都难 ... -
IBM JVM垃圾回收原理——1
2010-04-06 15:42 1575原文下载:IBM Garbage Collection ... -
Java 理论与实践: 垃圾收集简史
2010-04-06 14:34 754垃圾收集的好处是无 ... -
关注性能: 调优垃圾收集
2010-04-06 14:08 756随着网志作为公共日 ... -
Java 理论与实践: JVM 1.4.1 中的垃圾收集
2010-04-06 10:42 829老对象和年轻对象 ... -
搞懂java中的synchronized关键字
2010-04-01 19:54 778实际上,我关于java的基 ...
相关推荐
当系统的处理能力有某种变化趋势时,除了关于等待队列、执行线程,EJB池以及数据库连接池和StatementCache方面的调优外,还要考虑到Java垃圾收集器(GarbageCollection,本文简称GC)对系统性能的影响。本文介绍了...
1. 新的垃圾收集器:Java 17引入了新的垃圾收集器,称为ZGC和JDK 17中的其他一些优化。这些新的垃圾收集器提供了更好的内存管理和更高的吞吐量,从而提高了应用程序的性能。 2. 新的Java模块系统:Java 17引入了新...
Java 11主要包含了新的语法、改进的工具和增强的性能等方面的内容,如支持原始字符串字面量、增强了对lambda表达式中局部变量的类型推断、新增了G1垃圾收集器等。 Spring 5.0:Spring 5.0是Spring框架的最新版本,它...
垃圾收集对 Java 性能的影响 用跟踪程序分析性能 理解跟踪程序 跟踪程序使用示例 从命令行启动和控制跟踪程序 从程序启动和控制跟踪 使用 trcrpt 命令格式化报告 添加新的跟踪事件 报告性能问题 测量基线 什么是性能...
常见的垃圾收集算法以及垃圾收集器的特点和工作原理;常见虚拟机监控与故障处理工具的原理和使用方法。第三部分分析了虚拟机的执行子系统,包括类文件结构、虚拟机类加载机制、虚拟机字节码执行引擎。第四部分讲解了...
例如,在32G内存的机器上,适当配置Kafka的堆大小和垃圾收集器可以大幅提高性能。消息的可靠性取决于acks的设置,它决定了消息发送者需要等待多少确认。acks=0提供最高吞吐量但最易丢失消息,而acks=all则确保了最高...
更好的性能优化:JDK 11通过垃圾收集器的改进、字节码编译器的优化以及新的JIT编译特性,提升了应用程序的运行性能,使其更加高效和稳定。 新特性和语言改进:JDK 11引入了一些令人激动的新特性,如局部变量类型...
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 13、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)的...
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 16、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)...
性能优化和减少的垃圾收集 重构的应用程序部署器,具有可选的独立部署器,允许在Web应用程序投入生产之前进行验证和编译 使用JMX和管理器Web应用程序完成服务器监视 可扩展性和可靠性增强 改进了Taglibs的处理,包括...
第十三章 事件和索引指示器 .148 13.1 事 件 .148 13.2 索引指示器 .151 13.3 小 结 .154 第十四章 继 承 .155 14.1 C#的继承机制.155 <<page 3>> page begin==================== 14.2 多 态 性 ....