龙空技术网

生产环境宕机问题处理系列之解决WebSphere的内存溢出问题

汪藏海天 449

前言:

如今各位老铁们对“was查看javahome”大体比较珍视,朋友们都想要剖析一些“was查看javahome”的相关知识。那么小编也在网络上收集了一些对于“was查看javahome””的相关知识,希望小伙伴们能喜欢,姐妹们一起来了解一下吧!

在基于WebSphere Application Server的Web应用程序中,内存利用率会严重影响系统性能。 最常见的内存问题之一是内存泄漏,它会导致严重的性能下降。 从理论上讲,由于Java™具有垃圾回收(GC),因此不应在Java™中发生内存泄漏。 但是,GC仅清除不再引用的未使用对象。 因此,如果未使用但仍引用了对象,则GC不会删除该对象,这会导致JVM问题中的内存泄漏。 除了内存泄漏外,您可能遇到的其他内存问题还包括内存碎片,大对象和调优问题。 在许多情况下,这些内存问题可能导致应用程序服务器崩溃。 许多用户首先注意到应用服务器性能逐渐下降,并最终由于OutOfMemory异常而崩溃。

内存问题很难解决,因为它们有多种原因。 本文提供了识别不同内存问题的根本原因的方法及其相应的解决方案。 它还介绍了用于WebSphere Commerce V6测试中的内存问题确定方法。 WebSphere Commerce是部署在WebSphere Application Server上的最大J2EE应用程序之一。 该方法论可以在系统测试期间检测并解决WebSphere Commerce中的内存泄漏问题。

方法概述

图1显示了确定和解决内存问题的整个过程。 此图中列出了五种解决方案,以下各节将进一步说明:

调整最大堆调整Xk / Xp通过swprofiler识别调整缓存大小执行堆转储图1.内存分析方法的流程图

设置详细的垃圾收集以获取用于内存监视器的WebSphere Application Server日志

要分析应用程序服务器中的内存问题,第一步是收集GC信息。 您需要一个工具来分析此信息。

设置详细GC以获得用于内存监视器的WebSphere Application Server日志

要监视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示例来启用它:

通过输入来打开WebSphere Application Server管理站点。 该端口是HTTP管理端口的编号,默认情况下为9060。 输入一个ID(没有密码的任何ID)并登录。选择服务器>应用程序服务器> server1> Java和进程管理>进程定义> Java虚拟机 。选择“ 详细垃圾回收 ”,如图2所示。单击“ 应用” ,然后单击此页面顶部的“ 保存 ”。重新启动WebSphere Application Server。

图2.在WebSphere Application Server V6中启用详细GC

重新启动WebSphere Application Server之后,您会在native_stdout.log或native_stderr.log中看到详细的GC输出。

分析详细GC

有许多用于详细GC日志分析的工具,例如Tivoli®Performance Viewer,转储JVM(DMPJVM)和WebSphere的Resource Analyzer。 这些工具可以提取有用的信息,并说明JVM堆大小使用情况随时间变化的趋势。

在分析native_stdout.log或native_stderr.log之后,您应该生成包含以下信息的图表:

占用率(MB)分配速率(KB /秒)GC总暂停时间(毫秒)打标和扫描时间(毫秒)紧凑时间(毫秒)GC周期长度和分布(毫秒)GC之后的可用空间(MB)AF前的可用空间(分配失败)(MB)导致AF的请求大小(字节)

在这些图表中,有些图表有助于监视GC的效果并检测许多问题。 您可以使用“ GC周期长度和分布”来分析GC频率和分布,可以使用“ GC之后的可用空间”来分析内存泄漏,并可以使用“ AF之前的可用空间”和“导致AF的请求大小”来分析碎片或大对象。 其他图表也可以协助分析。

图3和4显示了“ GC之后的可用空间”的一些示例。 在正常的“ GC之后的可用空间”图中,应用程序正确地使用了Java™堆,红线应大致位于水平线上,如图3所示。在图4中,红线下降表示空闲可分配的空间正在减少。 如果怀疑内存问题,请继续运行测试,直到发生OutOfMemory异常,因为一段时间后可用空间的一些下降趋势将稳定下来。 如果问题与WebSphere Application Server或JDK有关,这将帮助您从WebSphere Application Server和JDK获得更好的支持。

图3.常规“ GC之后的可用空间”图表的示例

图4.带有问题的“ GC之后的可用空间”图表示例

分析碎片

如果存在内存问题,但是GC之后没有可用空间减少,请检查“ AF之前的可用空间”和“导致AF的请求大小”的图表。 AF意味着对象需要堆空间,但是JVM堆中没有足够的连续空间可用于该对象。 通常,AF将在JVM堆用完时发生。 但是,如果所有可用空间都被碎片化,也会发生AF,因此该对象没有连续的空间。 如果应用程序中有大型对象分配,则此问题会大大放大,因为对于这些大型对象而言,堆变得不太可能具有较大的连续空间。 “ AF前的可用空间”是指发生AF时的可用空间大小。 该空间应该是一个较小的值,因为发生AF时堆大小几乎用完了。 因此,红线始终在图表底部附近。 图5显示了正常使用,没有碎片问题。

严重的碎片会导致频繁的GC循环,从而降低性能。 GC频率上升是碎片化的另一个指标。

图5.正常的“ AF之前的可用空间”图表

调整最大堆大小

如果GC之后的可用空间没有减少,请检查GC周期长度和分布以及GC的总暂停时间。 如果自“ GC周期长度和分布”中最后一次AF以来的时间不太短,但是“ Total GC Pause Time”中的完整时间太长,则表明GC不太频繁,并且GC持续时间非常长。 每个GC周期的持续时间均应受到监控,并且不应超过10秒,除非周期内发生压实。 在这种情况下,堆可能对于应用程序而言太大,并且GC需要很长时间才能清理该大堆中的对象,因此请减小最大堆大小。 在其他情况下,GC频率太高,堆可能对于应用程序来说太小,并且GC需要频繁运行,因此请增加最大堆大小。

要调整JVM最大堆大小:

打开WebSphere Application Server管理控制台并登录。展开服务器>应用程序服务器> server1> Java和进程管理>进程定义> Java虚拟机 。将最大堆大小更改为更大的值。单击“ 应用” ,然后单击此页面顶部的“ 保存 ”。重新启动WebSphere Application Server。再次尝试测试用例,看看问题是否消失。

请注意,根据系统i调整指南 ,i5 /OS®不应有最大堆大小,因为分配模型与其他平台不同。 设置为无限制后,可能需要几天时间才能稳定到3 GB。

调整Xk / Xp

如果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中找到以下行:

<GC(VFY-SUM): pinned=4265(classes=3955/freeclasses=0) dosed=10388 movable=1233792 free=5658>

固定大小和类大小大约是-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大小。 调整之后,如果剩下碎片,则可以怀疑大对象问题。

图6.在WebSphere Application Server管理控制台中调整Xp / Xk

通过swprofiler识别

在两种情况下,您可以怀疑存在异常的大对象。 一种是在调整Xk和Xp参数后,是否仍然存在碎片问题。 在这种情况下,AF之前的可用空间具有很大的值,并保持在较高水平,如图7所示。发生AF时,可用空间甚至大于500 MB。 在这种情况下,请怀疑一些不寻常的大物体。

图7.发生AF时较大的可用空间

在另一种情况下,GC之后的可用空间正在减少。 AF请求空间不仅很大,而且还在增长,如图8所示。在这种情况下,您还可以怀疑大对象问题。

图8.随着AF请求空间的增长,GC下降之后的可用空间

要确定大对象问题,请使用swprofiler工具。 此工具可通过设置分配限制和深度来帮助您打印对象的堆栈信息。 要使用此工具:

下载profiler.zip文件,并将其解压缩。 请注意,在更高版本的JDK中,已经创建了一个内置函数来代替swprofile的使用。 有关详细信息,请参阅技术说明:如何识别发出分配请求大于特定大小的线程的Java堆栈 。从解压缩的文件夹中获取正确的lib文件,并将其复制到WebSphere Application Server安装文件夹下的bin路径。 例如,将此文件复制到WAS_Home\java\jre\bin 。对于AIX,Linux,zSeries上的Linux或Windows®平台,在WebSphere Application Server管理控制台的“ 通用JVM参数”字段中键入-Xrunswprof 。 如果您的平台是Solaris,则此命令是-Xrunallocprof 。重新启动WebSphere Application Server。

重新启动WebSphere Application Server之后,您将在native_stdout.log或native_stderr.log中看到有关swprofiler的信息,例如以下几行:

Swprofiler loaded OKAllocation limit: XXXX, Depth: YYY

您可以尝试配置此分配限制和深度。 此后,当JVM需要分配一个对象,该对象需要的空间大于分配限制时,该工具会在stderr日志中记录该分配。 在WebSphere Application Server V6中,设置极限值和深度值:

打开WebSphere Application Server管理控制台http:// hostname:port/ibm/console并登录。展开服务器>应用程序服务器> server1> Java和进程管理>进程定义>定制属性 。单击新建,然后添加两对属性和值,例如: ALLOC_LIMIT 600000ALLOC_DEPTH 10保存更改并重新启动服务器。

设置分配限制和深度(在此示例中为10个级别的线程堆栈)之后,您将在stderr日志中看到有关打印堆栈的以下信息:

<AF[591]: completed in 106 ms>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请求大小图是否正常。 重要的是要知道您无法删除碎片。 您只能在某种程度上减少或最小化。

图9.移除可疑大物体后,AF改善之前的可用空间

调整缓存大小

如果GC之后的可用空间随着AF的增加而下降,则很可能是缓存调整导致了内存问题。 缓存不一定意味着DynaCache。 它包括正在使用的其他类型的缓存。 一种解决方案是减小内存中的缓存大小,并在可能的情况下让溢出条目使用磁盘缓存。

有时,过多的缓存对象看起来像是内存泄漏,因为随着应用程序接收的负载增加,缓存会增长。 客户和测试人员需要找到一个稳定点,在该稳定点处,由于缓存的对象过多,系统不会产生OutOfMemory错误。 根据正在使用的堆大小调整缓存大小。 在图10中,该示例显示了OutOfMemory异常。 进一步检查后,您会看到缓存的页面大小为60-100 KB,缓存条目的数量设置为5000。因此,这1 GB堆中的一半分配给了缓存!

图10.由于缓存大小增加,可用空间达到零

在大多数情况下,您可以调整DynaCache的大小来消除此类问题。 要调整DynaCache的大小,请执行以下操作:

登录到WebSphere Application Server管理控制台。展开服务器>应用程序服务器> server1>容器服务>动态缓存服务>缓存大小 。设置所需的缓存大小值,如图11所示。保存更改并重新启动应用程序服务器。图11.调整DynaCache的大小

图12显示了将高速缓存条目的数量调整为3000,并启用磁盘卸载以使溢出条目使用磁盘高速缓存后,同一测试案例的内存使用情况。 在遇到OutOfMemory异常的第一次测试的持续时间的3倍之后,应用程序已将堆中的可用空间稳定在100 MB。 从图12中可以看到,开始时缓存正在预热,导致可用空间减少。 但是,快要结束时,高速缓存正在稳定,这意味着它现在已完全预热。

图12.减小缓存大小后的可用空间

执行堆转储

如果除“ GC下降后的可用空间”以外的所有图表均正常,则怀疑内存泄漏。 在这种情况下,建议执行堆转储。

有一些工具可以帮助您执行此分析。 我们使用了IBM JDK附带的实用程序IBM®HeapDump。 它使您可以将Java堆中的所有活动对象转储到一个名为heapdump的文本文件中。 该工具分析每个Java对象的内存使用情况。 这是查找其中哪些正在消耗JVM空间的步骤。

这是在WebSphere Application Server v6.0中设置堆转储的示例。 要配置IBM_HeapDump,请在WebSphere Application Server管理控制台中添加这些“名称和值”对,如图13所示。

图13.名称和值对

去做这个:

在管理控制台中,打开服务器>应用程序服务器> server_name> Java和进程管理>进程定义>环境条目>新建 。 从那里,您可以设置这些名称-值对。 此设置特定于WebSphere Application Server v6.0。 如果未设置IBM_HEAPDUMPDIR,那么缺省输出目录是应用程序服务器的根目录。保存您的修改并重新启动应用程序服务器。 记录您的应用程序服务器进程的JVM PID。在您想要收集堆转储时,可以通过运行kill -3 JVM_PID发出信号。 这将在heapdump.date.time.pid.txt下生成名为heapdump.date.time.pid.txt和javacore.date.time.pid.txt文件。 该工具在发生内存泄漏后的点向多个heapdump点发出信号。 这对于分析泄漏的根本原因很重要。

在不同的操作系统上,用于生成heapdump文件的命令是不同的:

在Solaris上,使用kill -HUP JVM_PID 。在大多数UNIX平台上,请使用kill -3 JVM_PID 。在Windows®系统上,有一系列导致堆转储的命令: WAS_HOME\profiles\instance_name\bin\wsadmin.batwsadmin>set jvm [$AdminControl completeObjectName type=JVM,process=server1,*]wsadmin>$AdminControl invoke $jvm dumpThreads

使用生成的heapdump和javacore文件,您可以分析导致此内存泄漏问题的原因。 存在各种分析工具可帮助进行此调查。 可以下载的一种有用的工具是HeapAnalyzer工具 。 该工具在分析堆转储文件后显示候选泄漏列表。

结论

本文介绍了基于WebSphere Application Server v6.0的J2EE应用程序中的内存问题的问题确定过程。 此过程可帮助系统管理员,测试人员和支持人员查找和确定WebSphere Commerce v6.0系统中的内存泄漏问题。 测试人员初步确定问题可以帮助缩短问题解决周期,减少找到解决方案的时间。

标签: #was查看javahome