简单-高效-优雅

[转帖]定位应用程序中对大对象的申请

用户在使用WebSphere Application Server(以下简称WAS)运行自己应用的时候经常会碰到Out Of Memory的问题(简称OOM问题)。其中很大一部分的情况是应用程序分配大对象造成的Java堆空间碎片问题。因此,如何快捷准确的找到分配大对象的 方法并加以改进是解决这类问题的关键。
本文会给出一个工具(swprof),针对WAS给出定位分配大对象的方法。需要注意的是该工具的启用可能会消耗大量的CPU计算资源,所以建议在测试环境中使用。

当用户在使用WAS的时候碰到了分配大对象引起的碎片问题。找到造成分配失败的线程堆栈信息对于解决问题将会是非常有帮助的。本文提供的工具可以帮助用户:
● 打印分配失败的线程堆栈信息
● 通过设置分配失败的内存大小,限制堆栈信息的打印
● 通过设置方法调用的深度,限制堆栈信息的打印
需要注意的是,这个工具在某些情况下可能无法报告堆栈中方法的准确名字。在这种情况下,用户需要通过其他机制找到大对象的分配方法或者联系本地的IBM技术支持。

为了使用本工具,用户首先需要按照下面的步骤配置java虚拟机,使其能够加载所需的类库:
1.从下面的连接中找到并下载Profiler.zip。展开这个压缩文件,可以看到Profiler.zip包含多个压缩文件。找到对应操作系统的压缩 文件,比如:swprof_Windows.zip对应Windows操作系统,展开并得到对应的类库文件,比如:libswprof.so或者 liballocprof.so或者swprofiler.dll。拷贝类库文件到<WAS_Home>"java"jre"bin路径下。
http://www-1.ibm.com/support/docview.wss?uid=swg21162314&aid=1
其中<WAS_Home>代表WAS的安装目录。
注意:这些类库文件针对每个操作系统是不同的,确保找到与操作系统对应的类库文件并拷贝到指定的路径下。
2.对于AIX、Linux、Linux on zSeries、Windows平台上的WAS,在Java虚拟机的命令行参数中添加:-Xrunswprof。对于Solaris平台上的WAS,在 Java虚拟机的命令行参数中添加:-Xrunallocprof。添加的具体办法请参考WAS的信息中心:
http://www-306.ibm.com/software/webservers/appserv/was/library/
3.重新启动应用服务器
4.如果,类库被成功的加载,那么在应用服务器启动过程的stderr日志中(比如:native_stderr.log)可以看到类似如下的信息:
swprofiler loaded OK
Allocation limit: XXXX, Depth: YYY
为了更好的利用该工具,用户可以定制打印堆栈的分配大小和深度。其中分配大小通过设定环境变量ALLOC_LIMIT来定制;分配深度通过设定变量 ALLOC_DEPTH来定制。每当应用程序尝试分配超过分配限制大小的对象时,工具就会在应用服务器的stderr日志中(比 如:native_stderr.log)打印申请这个对象的方法信息。分配深度控制着堆栈被打印的层数。两者的默认值是50000和20。这就意味着, 默认情况下当某个应用尝试分配超过50000个字节大小的对象时,工具将打印堆栈的头20层方法。例如:
……
<AF[591]: Allocation Failure. need 22616440 bytes, 6476 ms since last
AF>
<AF[591]: managing allocation failure, action=2 (118062832/674101760)>
<GC(591): GC cycle started Fri Dec 09 08:19:50 2005
<GC(591): freed 481241408 bytes, 88% free (599304240/674101760), in
105 ms>
<GC(591): mark: 90 ms, sweep: 15 ms, compact: 0 ms>
<GC(591): refs: soft 3 (age >= 32), weak 0, final 21, phantom 1>
<AF[591]: completed in 106 ms>
Large object allocated: size 22616428
at testalloc in class com/test/OOMTest 21616424
at service in class javax/servlet/http/HttpServlet
……
用户可以按照如下的方法设定这2个环境变量:
WAS V6.0:
1. 登陆WAS管理控制台依次选择:
服务器 > 应用服务器 > 服务器名称(比如:server1)> Java和进程管理 > 进程定义 > 环境条目 > 新建
2. 添加如下的环境变量和值:
名称 值
ALLOC_LIMIT 限定的字节数(比如:600000)
ALLOC_DEPTH 限定的堆栈深度(比如:10)
3. 保存设置重新启动应用服务器

WAS V5.0 & 5.1:
1. 登陆WAS管理控制台依次选择:
服务器 > 应用服务器 > 服务器名称(比如:server1)> 进程定义 > 环境条目 > 新建
2. 添加如下的环境变量和值:
名称 值
ALLOC_LIMIT 限定的字节数(比如:600000)
ALLOC_DEPTH 限定的堆栈深度(比如:10)
3. 保存设置重新启动应用服务器

Unix/Linux平台上的WAS V4.0 & 4.1:
1. 添加类似如下的2行在startupServer.sh脚本文件的开头,这个文件位于<WAS_Home>/bin路径下:
export ALLOC_LIMIT=600000
export ALLOC_DEPTH=10
2. 重新启动应用服务器

Windows平台上的WAS V4.0 & 4.1:
1.添加类似如下的2行在adminserver.bat脚本文件的开头,这个文件位于<WAS_Home>/bin路径下:
SET ALLOC_LIMIT=600000
SET ALLOC_DEPTH=10
2. 重新启动应用服务器

posted on 2008-04-24 17:50 BigOnion 阅读(328) 评论(0)  编辑  收藏 所属分类: 性能相关


只有注册用户登录后才能发表评论。


网站导航: