赞
踩
在基于WebSphere Application Server的Web应用程序中,内存利用率会严重影响系统性能。 最常见的内存问题之一是内存泄漏,它会导致严重的性能下降。 从理论上讲,由于Java™具有垃圾回收(GC),因此不应在Java™中发生内存泄漏。 但是,GC仅清除不再引用的未使用对象。 因此,如果未使用但仍引用了对象,则GC不会删除该对象,这会导致JVM问题中的内存泄漏。 除了内存泄漏外,您可能遇到的其他内存问题还包括内存碎片,大对象和调优问题。 在许多情况下,这些内存问题可能导致应用程序服务器崩溃。 许多用户首先注意到应用服务器性能逐渐下降,并最终由于OutOfMemory异常而崩溃。
内存问题很难解决,因为它们有多种原因。 本文提供了识别不同内存问题的根本原因的方法及其相应的解决方案。 它还介绍了用于WebSphere Commerce V6测试中的内存问题确定方法。 WebSphere Commerce是部署在WebSphere Application Server上的最大J2EE应用程序之一。 该方法论可以在系统测试期间检测并解决WebSphere Commerce中的内存泄漏问题。
图1显示了确定和解决内存问题的整个过程。 此图中列出了五种解决方案,以下各节将进一步说明:
要分析应用程序服务器中的内存问题,第一步是收集GC信息。 您需要一个工具来分析此信息。
要监视JVM内存的使用,请从WebSphere Application Server获取详细的垃圾回收(GC)日志; 即WebSphere Application Server安装目录dir / profiles / default / logs / server1目录下的native_stdout.log或native_stderr.log 。 WebSphere Application Server的缺省设置不会启用此功能,但是您可以使用以下WebSphere Application Server v6.0示例来启用它:
图2.在WebSphere Application Server V6中启用详细GC
重新启动WebSphere Application Server之后,您会在native_stdout.log或native_stderr.log中看到详细的GC输出。
有许多用于详细GC日志分析的工具,例如Tivoli®Performance Viewer,转储JVM(DMPJVM)和WebSphere的Resource Analyzer。 这些工具可以提取有用的信息,并说明JVM堆大小使用情况随时间变化的趋势。
在分析native_stdout.log或native_stderr.log之后,您应该生成包含以下信息的图表:
在这些图表中,有些图表有助于监视GC的效果并检测许多问题。 您可以使用“ GC周期长度和分布”来分析GC频率和分布,可以使用“ GC之后的可用空间”来分析内存泄漏,并可以使用“ AF之前的可用空间”和“导致AF的请求大小”来分析碎片或大对象。 其他图表也可以协助分析。
图3和4显示了“ GC之后的可用空间”的一些示例。 在正常的“ GC之后的可用空间”图中,应用程序正确地使用了Java™堆,红线应大致位于水平线上,如图3所示。在图4中,红线下降表示空闲可分配的空间正在减少。 如果怀疑内存问题,请继续运行测试,直到发生OutOfMemory异常,因为一段时间后可用空间的一些下降趋势将稳定下来。 如果问题与WebSphere Application Server或JDK有关,这将帮助您从WebSphere Application Server和JDK获得更好的支持。
如果存在内存问题,但是GC之后没有可用空间减少,请检查“ AF之前的可用空间”和“导致AF的请求大小”的图表。 AF意味着对象需要堆空间,但是JVM堆中没有足够的连续空间可用于该对象。 通常,AF将在JVM堆用完时发生。 但是,如果所有可用空间都被碎片化,也会发生AF,因此该对象没有连续的空间。 如果应用程序中有大型对象分配,则此问题会大大放大,因为对于这些大型对象而言,堆变得不太可能具有较大的连续空间。 “ AF前的可用空间”是指发生AF时的可用空间大小。 该空间应该是一个较小的值,因为发生AF时堆大小几乎用完了。 因此,红线始终在图表底部附近。 图5显示了正常使用,没有碎片问题。
严重的碎片会导致频繁的GC循环,从而降低性能。 GC频率上升是碎片化的另一个指标。
如果GC之后的可用空间没有减少,请检查GC周期长度和分布以及GC的总暂停时间。 如果自“ GC周期长度和分布”中最后一次AF以来的时间不太短,但是“ Total GC Pause Time”中的完整时间太长,则表明GC不太频繁,并且GC持续时间非常长。 每个GC周期的持续时间均应受到监控,并且不应超过10秒,除非周期内发生压实。 在这种情况下,堆可能对于应用程序而言太大,并且GC需要很长时间才能清理该大堆中的对象,因此请减小最大堆大小。 在其他情况下,GC频率太高,堆可能对于应用程序来说太小,并且GC需要频繁运行,因此请增加最大堆大小。
要调整JVM最大堆大小:
请注意,根据系统i调整指南 ,i5 /OS®不应有最大堆大小,因为分配模型与其他平台不同。 设置为无限制后,可能需要几天时间才能稳定到3 GB。
如果GC之后的可用空间没有减少,但是自“ GC周期长度和分布”中的最后一次AF以来的时间始终很小,则可能存在一些大对象或堆碎片。 您可以尝试调整Xk / Xp参数以删除大部分碎片。
解决方案是将不可移动对象组合到池中,以使它们不会将Java堆分成碎片。 在Java SDK 1.4.2中,GC将kCluster分配为堆底部的第一个对象。 kCluster是专门用于类块的存储区域。 然后,GC将pCluster分配为堆上的第二个对象。 pCluster是用于分配任何固定对象的存储区域。 当缺省kCluster大小不足以分配所有类块时,可以使用-Xk和-Xp选项指定kCluster和pCluster大小。
GC跟踪为版本1.4.2中的最佳Xk和Xp值提供了指南。 您可以通过在WebSphere Application Server管理控制台的“通用JVM参数”字段中键入-verbosegc -Dibm.dg.trc.print=st_verify来启动此命令。 保存更改并重新运行测试用例后,您可以在native_stdout.log中找到以下行:
固定大小和类大小大约是-Xk参数所需的大小。 建议将报告值增加10%(3955)。
pinned (=4265)和classes (=3955)之间的差异为pCluster的初始大小提供了指南。 您可以使用-Xp命令行选项指定pCluster和pCluster溢出大小:
-Xpiiii[K][,oooo[K]]
iiii以KB为单位指定初始pCluster的大小,并且oooo可选)以KB为单位指定溢出(后续)pClusters的大小。 iiii的默认值为16 KB,oooo的默认值为2 KB。
图6是设置Xk和Xp的示例,该示例在Generic JVM参数中指定-Xk22000 -Xp64k,16k 。 如果问题仍然存在,请尝试使用更高的初始pCluster设置和溢出的pCluster大小。 调整之后,如果剩下碎片,则可以怀疑大对象问题。
在两种情况下,您可以怀疑存在异常的大对象。 一种是在调整Xk和Xp参数后,是否仍然存在碎片问题。 在这种情况下,AF之前的可用空间具有很大的值,并保持在较高水平,如图7所示。发生AF时,可用空间甚至大于500 MB。 在这种情况下,请怀疑一些不寻常的大物体。
在另一种情况下,GC之后的可用空间正在减少。 AF请求空间不仅很大,而且还在增长,如图8所示。在这种情况下,您还可以怀疑大对象问题。
要确定大对象问题,请使用swprofiler工具。 此工具可通过设置分配限制和深度来帮助您打印对象的堆栈信息。 要使用此工具:
重新启动WebSphere Application Server之后,您将在native_stdout.log或native_stderr.log中看到有关swprofiler的信息,例如以下几行:
Swprofiler loaded OKAllocation limit: XXXX, Depth: YYY
您可以尝试配置此分配限制和深度。 此后,当JVM需要分配一个对象,该对象需要的空间大于分配限制时,该工具会在stderr日志中记录该分配。 在WebSphere Application Server V6中,设置极限值和深度值:
设置分配限制和深度(在此示例中为10个级别的线程堆栈)之后,您将在stderr日志中看到有关打印堆栈的以下信息:
Large object allocated: size 22616428at testalloc in class com/test/OOMTest 21616424at service in class javax/servlet/http/HttpServlet
最后一步是通过在native_stderr.log中找到“大对象”来找到可疑的大对象。 如果问题在于如图8所示的对象增长,请查找并修复尺寸增大的对象。 解决大对象问题后,请确认新的GC后可用空间,AF前可用空间和AF请求大小图是否正常。 重要的是要知道您无法删除碎片。 您只能在某种程度上减少或最小化。
如果GC之后的可用空间随着AF的增加而下降,则很可能是缓存调整导致了内存问题。 缓存不一定意味着DynaCache。 它包括正在使用的其他类型的缓存。 一种解决方案是减小内存中的缓存大小,并在可能的情况下让溢出条目使用磁盘缓存。
有时,过多的缓存对象看起来像是内存泄漏,因为随着应用程序接收的负载增加,缓存会增长。 客户和测试人员需要找到一个稳定点,在该稳定点处,由于缓存的对象过多,系统不会产生OutOfMemory错误。 根据正在使用的堆大小调整缓存大小。 在图10中,该示例显示了OutOfMemory异常。 进一步检查后,您会看到缓存的页面大小为60-100 KB,缓存条目的数量设置为5000。因此,这1 GB堆中的一半分配给了缓存!
在大多数情况下,您可以调整DynaCache的大小来消除此类问题。 要调整DynaCache的大小,请执行以下操作:
图12显示了将高速缓存条目的数量调整为3000,并启用磁盘卸载以使溢出条目使用磁盘高速缓存后,同一测试案例的内存使用情况。 在遇到OutOfMemory异常的第一次测试的持续时间的3倍之后,应用程序已将堆中的可用空间稳定在100 MB。 从图12中可以看到,开始时缓存正在预热,导致可用空间减少。 但是,快要结束时,高速缓存正在稳定,这意味着它现在已完全预热。
如果除“ GC下降后的可用空间”以外的所有图表均正常,则怀疑内存泄漏。 在这种情况下,建议执行堆转储。
有一些工具可以帮助您执行此分析。 我们使用了IBM JDK附带的实用程序IBM®HeapDump。 它使您可以将Java堆中的所有活动对象转储到一个名为heapdump的文本文件中。 该工具分析每个Java对象的内存使用情况。 这是查找其中哪些正在消耗JVM空间的步骤。
这是在WebSphere Application Server v6.0中设置堆转储的示例。 要配置IBM_HeapDump,请在WebSphere Application Server管理控制台中添加这些“名称和值”对,如图13所示。
去做这个:
在不同的操作系统上,用于生成heapdump文件的命令是不同的:
使用生成的heapdump和javacore文件,您可以分析导致此内存泄漏问题的原因。 存在各种分析工具可帮助进行此调查。 可以下载的一种有用的工具是HeapAnalyzer工具 。 该工具在分析堆转储文件后显示候选泄漏列表。
本文介绍了基于WebSphere Application Server v6.0的J2EE应用程序中的内存问题的问题确定过程。 此过程可帮助系统管理员,测试人员和支持人员查找和确定WebSphere Commerce v6.0系统中的内存泄漏问题。 测试人员初步确定问题可以帮助缩短问题解决周期,减少找到解决方案的时间。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。