`
womendu
  • 浏览: 1513549 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

WebSphere性能调优-垃圾收集器

 
阅读更多

基于WebSphere 构建的企业应用,时常会出现性能问题,在严重的情况下还会提示出内存溢出这是一件很让人恼怒的事情。在WebSphere Application Server(Was)运行的时候,内存溢出,会生成大量的溢出文件,如Javacore, Heapdump等文件,占用了大量的磁盘空间。在这种情况下,时常会出现一连串的系统问题,如部署在Was的所有应用服务都报错,Was连控制台也无法访问等。

为解决问题,我们通常会选择重新启动整个Was或者服务器,然后分析运行日志SystemOut.logystemErr.logative_stdout.lognative_stderr.log 和系统内存溢出的时候产生的JavacoreHeapdump文件来寻找出问题。

那么,为什么会出现内存溢出呢?

应用服务器在运行过程中需要创建很多对象,而在应用服务器的堆空间大小有限的情况下,请求进程不断申请空间来创建与存放对象,在达到上限时而服务器又没能释放出空间来处理申请空间的请求就会出现内存溢出情况。这就像吹气球,当气球中的气体到达一定程度时,气球就会被撑爆。(32位的JDKJvm堆空间分配最大支持1.5G的大小,超过则无法正常启动。而64位的JDK堆大小分配无限制,其大小受到服务器的内存限制。)通常在投入生产的系统中,出现溢出一般都是对象分配不合理导致的。

在此,让我们先了解下Java世界里,对象与对象管理是怎么一回事。

Java的体系中,所有的类作为一个对象(包括Jdk本身提供的类,应用中由开发人员编写的类),都是直接或者间接继承了Java.lang.object产生的。这些类被创建的时候都会向Jvm堆申请一定的内存空间存放,因此在Jvm堆空间里会存放各式各样的对象,有的是静态类型,有的是私有类型等等,而这些对象都是通过垃圾收集器进行管理的。

垃圾收集器(Garbage Collection,我们通常称之为GC),它是JavaC++语言的一个显著的不同点。Java语言通过垃圾收集器管理内存中的对象,垃圾收集器是在C++基础上的一种极大进步,使许多编程问题消失于无形中。通过垃圾回收,在Java编程过程中,内存漏洞的情况会少得多。

虽然垃圾收集器为开发带来了极大的便利,但如果对象分配与使用不合理,也会导致垃圾回收在性能上拖Jvm的后腿。为了解决性能问题,GC则是一个让我们不能忽视的问题。根据不同的应用场景,选择适合的GC策略,可以帮助系统性能在一定程度上得到显著的优化。

垃圾收集器为了快速清除在JVM堆中不再使用的对象,从而释放出空间来供其他请求创建对象,常见的方法有引用计数方法和对象引用遍历方法等算法,目前主流的方法为对象引用遍历方法。通过这些高效的算法实现的GC策略有许多种,他们都是针对各种应用场景而产生的,我们可以通过在JVM启动参数中设置,来调整GC策略。

IBM SDK 5.0提供了四种不同的GC策略优化配置(IBM WebSphere 6.1版本开始,IBM JDK 升级到IBM SDK5.0,也就是常说的JDK1.5),详细如下:

 

 

序号

策略

选项

描述

备注

1

针对吞吐量进行优化

-Xgcpolicy:optthruput

WAS默认策略。对于吞吐量比短暂的 GC 停顿更重要的应用程序,通常使用这种策略。每当进行垃圾收集时,应用程序都会停顿。

 

2

针对停顿时间进行优化

-Xgcpolicy:optavgpause

通过并发地执行一部分垃圾收集,在高吞吐量和短 GC 停顿之间进行折中。应用程序停顿的时间更短。

 

3

分代并发

-Xgcpolicy:gencon

以不同方式处理短期存活的对象和长期存活的对象。采用这种策略时,具有许多短期存活对象的应用程序会表现出更短的停顿时间,同时仍然产生很好的吞吐量。

推荐使用

4

子池

-Xgcpolicy:subpool

采用与默认策略相似的算法,但是采用一种比较适合多处理器计算机的分配策略。建议对于有 16 个或更多处理器的 SMP 计算机使用这种策略。这种策略只能在 IBM pSeries® zSeries® 平台上使用。需要扩展到大型计算机上的应用程序可以从这种策略中受益。

 

 

 

Sun Jvm也有自己特色的GC策略,如:

 

序号

策略

选项

描述

备注

1

并发收集器

-XX:+UseConcMarkSweepGC

并发收集器与应用程序同时运行。这些收集器在某点上(比如压缩时),一般都不得不停止其他操作,以完成特定的任务,但是因为其他应用程序可进行其他的后台操作,所以中断其他处理的实际时间大大降低。

 

2

并行收集器

-XX:+UseParallelGC

并行收集器使用某种传统的算法,并使用多线程并行地执行它们的工作。在多cpu机器上使用多线程技术可以显著的提高java应用程序区性的可扩展性。

 

3

串行收集器

-XX:+UseSerialGC

用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高。但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器。当然,此收集器也可以用在小数据量(100M左右)情况下的多处理器机器上。

 

 

 

通过以上的列表数据,大家也接触到了各种常见的GC策略,相信到此对GCGC策略也有了一定程度的了解。那如何衡量GC的性能,如何为何业务应用选择合适的GC策略呢?

 

一般来说,衡量GC效率的参数主要有2类,吞吐量和停顿时间。

 

吞吐量是应用程序处理的数据量。衡量吞吐量的标准是与具体应用程序相关的。

停顿时间是垃圾收集器将所有应用程序线程停下来,从而对堆进行收集所经历的时间。

 

如何分析和选择适合的GC策略呢?我们可以在业务应用系统打开详细垃圾回收,收集系统在运行过程中的GC日志,通过分析GC日志,来判断当前GC策略是否符合当前应用系统。

 

在实际应用场景中,不是每个应用服务都必须调整GC,如果您寄予厚望希望调了GC策略后,就一定能使系统达到性能上的提升,成效未必尽入人意。因此GC策略调整只是从GC角度去辅助性能优化,而调优的效果需要根据实际情况才能断定。例如:在测试机调整了GC策略,使用压力测试工具进行压力测试,性能优化成效显著;但在生产系统上调整了参数,却未收到让人满意成效,且生产机比测试机配置高,这些问题已经是屡见不鲜了,问题原因有很多方面,通常是因为生产实际使用场景与测试机压力测试场景不一致,系统受到的压力不一样所导致的。

 

GC调整在系统能够性能调优上确是一个必不可少的环节,合理的创建使用对象,选择适合的GC策略,往往能让性能有一定的提高,也减少了内存溢出的可能性,或者缩短系统停顿的时间。

 

以下是一段发生在IBM SDK5.0版本上配置了分代并发策略所产生的GC日志,让我们一起看下如何分析这一段GC

 

 

 

<!—距离上次GC间隔时间为6.787

<af> 表示本次垃圾回收是因为分配失败而引发的,如果标签开头写着sys,则表示应用中有显示调用GC,System.gc()。一般情况下不建议显示调用GC,当然也可以通过配置防止显示GC, JVM启动参数中加入-Xdisableexplicitgc参数屏蔽显式GC

Type=“nursery” :这次GC的类型是新生代方式,因为新生代的分配失败而进行垃圾回收了。

 Id=”3365”代表GC发生在新生代,已经重复执行了3365

timestampGC的执行时间

-->

<af type="nursery" id="3365" timestamp="  1 06 16:09:03 2010" intervalms="6787.454">

 

  <!—这里记录需要申请的堆大小为710824b 694KB -->

<minimum requested_bytes="710824" />

 

  <!—GC准备开始前 使用时间为 0.224 -->

<time exclusiveaccessms="0.224" />

 

<!—GC前堆空间使用情况,可以看到剩余567408B,不能满足空间的申请要求了,申请空间是710824B,因此就需要进行GC -->

  <nursery freebytes="567408" totalbytes="42694656" percent="1" />

 

  <!--   GC前的堆空间情况,JVM堆大小为1.2左右了,空闲的空间为650mb左右,大致空闲空间为48%

Tenured:长存(tenured 区域

Soa:小对象使用区域;就是正常的堆。所有对象最初都分配给小对象区域,但是如果小区域已经分配完了,则将大于 64KB 的对象分配给大对象区域。

Loa:大对象使用区域;大对象区域是堆中保留给大对象分配的一小片区域。如果应用程序不需要大对象区域(也就是应用程序不分配任何大对象),内存管理例程会快速将大对象区域缩减为空,这样,整个堆都可以供正常的分配使用。

 -->

  <tenured freebytes="666933424" totalbytes="1365881856" percent="48" >

    <soa freebytes="654641328" totalbytes="1353589760" percent="48" />

    <loa freebytes="12292096" totalbytes="12292096" percent="100" />

  </tenured>

 

<!—GC后堆空间使用情况 -->

<!—详细gc情况

type="scavenger":垃圾回收类型为清理过程。

id="3365": 意为执行力3365次清理,并且没有发生过全局GC,如 <gc type=”global”>

<flipped objectcount="15558" bytes="3973128" />:说明将要把15558个存活下来的对象被复制到了幸存区(survivor space

<tenured objectcount="14791" bytes="14233400" />:说明将要把14791个对象则经过多次幸存区的复制,被转移到了长存区(tenured

 

<scavenger tiltratio="65" />:清理的倾斜比率为65%

<refs_cleared soft="73" weak="61" phantom="0" />:清理了存在引用对象的数目. 弱引用为61、软引用为73,和虚引用为0. 弱引用、软引用和虚引用允许灵活的缓存,能够改进应用程序的内存特性。如果引用对象过多大于1000GC停顿时间就会受到影响。因此我们需要检查是否存在过多的应用对象。

<finalization objectsqueued="40" />:收尾器,存在需要在GC后,要调用的自定义方法的对象。

 

-->

  <gc type="scavenger" id="3365" totalid="3709" intervalms="6788.531">

    <flipped objectcount="15558" bytes="3973128" />

    <tenured objectcount="14791" bytes="14233400" />

    <refs_cleared soft="73" weak="61" phantom="0" />

    <finalization objectsqueued="40" />

<scavenger tiltratio="65" />

 

<!—GC后的情况

nursery

1、清理了出空闲堆大小为39108112b  约为38191.515625KB,约为37MB

   2 总大小为44144640B,43110KB 约为42MB

-->

<nursery freebytes="39108112" totalbytes="44144640" percent="88" tenureage="1" />

 

<!—

Tenured长存区总大小为1365881856B,约为1.27GB

   空闲堆大小为 651143448B  620MB

 -->

 

    <tenured freebytes="651143448" totalbytes="1365881856" percent="47" >

      <soa freebytes="638851352" totalbytes="1353589760" percent="47" />

      <loa freebytes="12292096" totalbytes="12292096" percent="100" />

    </tenured>

    <time totalms="25.029" />

  </gc>

 

<!--这里再次打印需要申请的堆大小为710824b 694KB -->

<minimum requested_bytes="710824" />

 

<!--通过比较,就可以知道当前次的GC情况,及堆空间的使用率

<time totalms="26.386" /> 总的GC时间为26.386ms

 -->

  <nursery freebytes="38397288" totalbytes="44144640" percent="86" />

  <tenured freebytes="651143448" totalbytes="1365881856" percent="47" >

    <soa freebytes="638851352" totalbytes="1353589760" percent="47" />

    <loa freebytes="12292096" totalbytes="12292096" percent="100" />

  </tenured>

  <time totalms="26.386" />

</af>

<!-- 经过垃圾回收,新生代的空间剩余86%,因为分配失败发生在新生代,进行的是快速的Minor gc,所以长存区的可用空间依然是47%,这次回收的时间为26.386ms。而

在长存区发生的是Major gc,回收时间一般要长于Minor gc,一般健康的JVM 环境Minor gcMinor gc=110   -->

 

 

 

 

打开详细垃圾回收,我们就可以获得详细垃圾回收情况,根据以上的GC日志的分析,我们则可以了解到系统GC提供了什么样的信息给我们。通过这些信息,我们可以分析得出当前GC策略是否需要调整。(当然这个与您实际生产得出的GC日志分析结果有关)

 

在分析的过程里,我们需要关注几个点,来分析GC策略是否需要调整:

l   GC频率:多长时间执行一次GC,如果GC频繁的话,则需要检查系统现在的运行情况是否合理

l   GC类型+GC申请空间大小+新生代空间大小:分析GC是否合理

l   各分代区域的大小:检查当前JVM堆的使用是否合理,新生代的空间大小是否符合当前业务场景要求。长存区的空间大小是否合理,再联合JVM配置的堆配置大小分析,堆的使用是否存在问题,因为虽然进行了GC,但堆空间的使用如不能满足要求的话,易导致系统出现全局GC,在压力过大的情况下还会内存溢出。

l   重点检查GC过程中长存区的变化:是否存在大对象,如果有的话,可以考虑-Xlp参数优化

l   GC过程中是否清理了过多引用对象:如有则需要检查应用

l   GC整个过程消耗的时间是否过长:过长的GC会直接影响到系统的性能,当然这个也GC类型有关,全局GC,清理长存区的GC时间相对会长点,但是这些类型的GC不会很频繁。

 

以上主要是通过详细分析GC日志,从而协助我们进一步了解到JVM堆的使用情况,最后得出当前GC策略是否符合业务应用使用场景,而更换其他GC策略则需要配合当前业务场景与JVM堆使用情况去选择适合的GC策略。

 

JDK的版本不同,GC的策略配置也有所不同,但这不是重点,如何读懂GC日志,分析JVM堆的使用情况后,更根据问题去寻找适合的JVM选项参数进行设置,从各方面去调整最终达到一个性能调优的目地。

 

由此可见,垃圾回收的调整在性能调优过程中也是一个十分重要的环节。

 

2
2
分享到:
评论

相关推荐

    Java性能调优--关于垃圾回收机制的分析和指导

    Java的垃圾收集器(Garbage Collector)会自动执行这一过程,减少了程序员对内存管理的直接操作,从而降低了编程错误的可能性。 然而,垃圾收集并非没有代价。它的主要缺点是可能导致程序性能下降,因为GC运行时会...

    WAS性能调优对jvm、线程数、ORB大小的配置

    1. **垃圾收集器选择**:WebSphere性能调优-垃圾收集器.docx文件可能涵盖了不同类型的垃圾收集器,如Parallel GC、CMS (Concurrent Mark Sweep) 和G1 GC。选择合适的垃圾收集策略可以平衡停顿时间与内存利用率。例如...

    websphere V6调优概要(红皮书)

    关键参数包括堆大小(MaxHeapSize和InitialHeapSize)、垃圾收集策略以及新生代与老年代内存分配比例。合理的JVM配置能够避免频繁的垃圾回收,减少应用暂停时间。 3. **线程池配置** WebSphere V6中的线程池管理是...

    Websphere portal tuning调优

    本章节主要介绍在WebSphere Portal V6.0环境下如何进行系统性能调优。性能调优是确保应用程序能够在高负载下保持稳定运行的关键步骤。通过对应用服务器、数据库服务器、目录服务器以及网络等关键组件的合理配置,...

    WebSphere应用服务器Java虚拟机性能调优与诊断

    - **垃圾收集器** - **解释器** - **异常处理机制** - **类加载器** - **可插拔组件** - **线程模型** - **JVM 分析工具** - **调试器** - **实时分析工具** #### WAS 所使用的不同 JVM WAS 可以支持多种 JVM,包括...

    案例研究 调优 WebSphere Application Server V7 性能

    调整 JVM 参数,如堆大小 (-Xms, -Xmx),新生代和老年代的比例,垃圾收集器设置等,可以显著影响应用程序的性能和稳定性。 - 选择合适的垃圾收集器,例如 CMS 或 G1,对于减少停顿时间和提高响应速度至关重要。 - ...

    精品:java虚拟机分析与优化PPT

    - JVM的核心运行时主要用C/C++开发,并且大多数功能在本地代码中执行,例如垃圾收集器、内存管理单元(MMU)、即时编译器(JIT)等。 - J2SE/J2EE API位于Java代码层,提供了数据结构和访问所需功能的方法,并允许与...

    Websphere日常监控手册

    这些变量主要用于控制垃圾收集器的行为,当系统遭遇内存不足时,能够自动生成堆转储(HEAPDUMP)和Java核心文件(JAVACORE),以便后续分析。 - **IBM_HEAPDUMP**: 设置为`true`,表示允许生成堆转储。 - **IBM_...

    IBM JDK5垃圾收集策略

    在这种策略下,垃圾收集器会尽可能地减少对应用程序运行的影响,以提高整体的吞吐量。然而,这意味着在垃圾收集过程中,应用程序可能会经历较长的停顿时间。 2. **针对停顿时间进行优化(-Xgcpolicy:optavgpause)*...

    IBM WebSphere Performance Tool / ISA / jca457.jar / ha456.jar / ga439.jar

    通过分析这个日志,开发者和运维人员可以了解垃圾收集器的行为,包括何时启动、耗时多久、回收了多少内存等,这对于调整JVM参数以优化WebSphere性能至关重要。例如,如果频繁的垃圾收集导致应用暂停时间过长,可能...

    GCCollector

    1. **实时监控**:GCCollector可以实时监控JVM的内存状态,包括堆内存使用情况、垃圾收集器的工作状态等。 2. **详细日志**:它能生成详细的GC日志,帮助分析GC活动的模式,找出可能的问题点。 3. **性能分析**:...

    websphere安装及配置说明

    根据性能分析结果进行必要的调优,如调整内存分配、减少垃圾收集频率等。 在提供的压缩包中,您会发现详细的文档说明和相关的截图,这些资料将进一步指导您完成Websphere的安装和配置。请仔细阅读并参照操作,如有...

    j2ee面试宝典及面试总结题

    - JVM内存模型,垃圾收集器的选择与调优。 - SQL查询优化,数据库索引的建立与使用。 - 负载均衡和集群配置,提高系统可用性和可扩展性。 通过深入学习并熟练掌握以上知识点,可以极大地提升你在J2EE面试中的...

    Java虚拟机分析与优化

    JVM的核心运行时组件通常用C或C++编写,并以原生代码的形式执行大部分功能,例如垃圾收集器、内存管理单元(MMU)、即时编译器(JIT)等。此外,JVM还提供了大量的输入/输出子例程以及操作系统调用接口。 Java 2...

    IBM gc分析工具 ga441.rar

    2. **可视化展示**:通过图形化界面展示GC活动的时间线,使用户能够直观地看到不同垃圾收集器的工作状态和内存使用变化。 3. **性能指标分析**:计算并显示关键性能指标,如平均GC时间、最大暂停时间、内存利用率等...

    Jvm堆栈dump文件分析

    总的来说,HeadAnalyzer 4.1.4是WebSphere环境下Java性能调优的重要工具,通过深入解析dump文件,它能帮助我们更好地理解和解决JVM相关的问题,提升系统的稳定性和性能。同时,配合`license`文件,可能还涉及到软件...

    IBM JDK6 SR15安装版

    5. **垃圾收集器**:IBM JDK提供了多种垃圾收集器选项,如Parallel GC、Concurrent Mark Sweep (CMS) 和Garbage First (G1) GC,这些GC策略可以根据不同的应用场景进行选择和调整,以达到最佳的内存管理和性能。...

    J2EE企业级项目开发-3期(KC007) 3.1 WebLogic文档.doc

    WebLogic运行在JVM上,因此理解JVM的内存模型、垃圾收集机制以及JVM参数调优对于优化WebLogic的性能至关重要。这包括堆大小设置、年轻代和老年代的划分、类加载器行为以及JVM性能监控工具的使用。 **WebLogic的管理...

    常见的Java面试题30题附答案.pdf

    2. **JVM(Java Virtual Machine)**:Java 程序运行在 JVM 上,了解JVM的内存模型(堆、栈、方法区等),类加载机制以及如何进行性能调优是必备技能。 3. **异常分类**:Java 异常分为检查型异常(Checked ...

Global site tag (gtag.js) - Google Analytics