EAS服务器内存溢出、宕机解决方案-Heapdump与JavaCore分析

转自 http://121.32.28.234:8800/kdwiki/index.php?doc-view-121.html

主要是为了自己学习HeapDump的分析,这是一篇好文章。

EAS服务器内存溢出、宕机解决方案

            场景描述:  EAS服务器运行一段时间后,客户端与portal登陆时,出现内存溢出的错误。有时甚至出现服务器直接宕机了,管理控制台也启动不了,客户端与portal都连接超时,必须使用EAS自带的stopserver.sh命令去终止服务器再重启。

解决思路:

1、情报收集

内存溢出后,到EAS服务器目录:eas\server\profiles\server*\bin下,看是否有类似:heapdump.20110718.120928.3804.0010.phdJavacore*.txt的文件生成。(注:默认情况下,如果使用sunjdk内存溢出时是不自动生成此类文件的,只有用ibmjdk才会自动生成。)如果没有找到此类文件,请切换EAS服务器使用ibmjdk,重启服务器后继续观察。(具体切换步骤请看附录2)。

 

2、分析Heapdump文件和Javacore文件

   ØHeap DumpJVM内存DumpHeapDump文件)。通过对它的分析可以快速诊断导致内存消耗的原因。Heapdump文件包含了在堆内存中的所有对象,可以理解为系统发生内存溢出(OutOfMemory,即OOM)时堆内存的快照。

      ØJavacore:与heapdump对应的线程堆栈信息,一般通过对它的分析可定位到发生内存溢出的功能点。

      ØHeap Dump分析工具:Heap Analyzer 下截地址:http://www.alphaworks.ibm.com/tech/heapanalyzer/download

   一般情况下,解析heapdump文件需要64位的jdk,并要求机器内存>=4G。因此一般都需要用客户的测试服务器或服务器上进行解析,普通的PC机完成此项任务。

 Ø工具准备好后,可到命令行下启动Heap Analyzer工具。

   命令如下:C:\Kingdee7\eas\jdk\bin\java -Xmn512m –Xmx4000m -jar ha414.jar

    (如果解析过程中内存溢出,可跟据实际情况调大–Xmx这个参数)

2.1打开HeapDump文件

 

Heap Analyzer工具打开后,点击以下图标选择打开heapdump文件:

 

1、打开heapdump文件会消耗系统的CPU、内存资源,系统性能会有所下降。建议尽量不在客户正式环境执行!如果实在没有其他机器,正式环境资源充足,且问题比较紧急,可以尝试使用正式环境。打开分析完后及时关闭以释放资源。

2、在打开过程中,出现如下图形,说明工具设置的最大内存不够,不能打开该文件,需采用ibm jdk来设置更大的最大内存来打开

 

 

2.1 HeapDump文件的分析     

名称解释

Root object:没有任何一个对象引用(持有)它

Parent object:对象A引用X,引用YA>X , A>Y…),A就是父对象

Child object:对象XA引用,被B引用等(A>X , B>X…),X就是子对象。

Owner object:因为子对象可能被多个父对象引用,但只能为其中一个父对象所有,这个父对象就是Owner objectTotal size的计算会涉及到Owner object,这是为了避免重复计算

Size :对象自身的大小(持有该对象的指针在内存中占用的大小)

Total Size:对象自身及子对象的和

功能介绍

1,界面打开后初始状态如下,主要对tree view这个视图进行分析,可最大化这个视图

2 tree view每一行的结构如下:

TotalSize(占用总内存百分比)[对象自身大小]子对象个数对象名称内存地址

3、泄漏一般发生在那些拥有“超乎寻常多”的引用(子节点)的class上,正是这些创建后没有释放、累积了成千上百的对象,造成了OutOfMemory。通过“Locate a leak suspect”和“Go to the largest drop in subtrees”可快速定位到子对象多的对象位置。

4、通过“show from roots”可以回到根节点

         

5、 通过“List same type”可以列出所有在内存中和该对象相同类型的对象。

   

附录1

示例1

选中占比最大的那个对象,右键选择“Locate a leak suspect”:

 

 

 

或者也可以直接点击“Subpoena Leak Suspect(s)”,然后选择占比最大的对象:

 

可以看到如下:

   

    步骤2 右键展开上图中LRUMap对象,如下

  

   

    步骤 3     对上图中的RowSetSqlDec对象右键点“List same type”,可看到该对象有3001个,共占用了700M内存:

    

    

 

示例2(结合javacore文件进行分析)

 

主要内存占用在如下三个部分

 展开上述内存占用

与调拔入库单相关的对象(分录)占用了2百多兆

还是与库存相关的对象(单据头)相关占用1百多兆

与调拔入库单相关的对象共占用4百多兆内存,

分析javacore文件(用dump文件中的看到的关键字MoveInWareBill来搜索),摘取的线程堆栈如下:

at java/lang/String.toLowerCase(String.java:1143(Compiled Code))

at com/kingdee/eas/scm/common/app/AbstractSCMBillBaseControllerBean._getCollection(AbstractSCMBillBaseControllerBean.java:181)

at com/kingdee/eas/scm/im/inv/app/AbstractInvBillBaseControllerBean._getCollection(AbstractInvBillBaseControllerBean.java:174)

at com/kingdee/eas/scm/im/inv/app/AbstractMoveInWarehsBillControllerBean._getCollection(AbstractMoveInWarehsBillControllerBean.java:173)

at com/kingdee/eas/scm/im/inv/app/AbstractMoveInWarehsBillControllerBean.getMoveInWarehsBillCollection(AbstractMoveInWarehsBillControllerBean.java:161)

at com/kingdee/bos/transaction/EJBTxFacade/TxInvokerBean_LocalObjectImpl_2.INVOKE_SUPPORTS(Bytecode PC:4(Compiled Code))

at $Proxy591.getCollection(Bytecode PC:22)

at com/kingdee/bos/framework/DynamicObject.invoke(DynamicObject.java:57(Compiled Code))

at com/kingdee/bos/framework/DynamicObject.getCollection(DynamicObject.java:246)

at com/kingdee/eas/base/dap/app/DAPAppTools.execDataFilterMultiEntry(DAPAppTools.java:75(Compiled Code))

at com/kingdee/eas/base/dap/app/DAPTransformerControllerBean._innerTransform(DAPTransformerControllerBean.java:1028)

at com/kingdee/eas/base/dap/app/DAPTransformerControllerBean._transformForBotp(DAPTransformerControllerBean.java:1131)

at com/kingdee/eas/base/dap/app/DAPTransformerControllerBean._transform(DAPTransformerControllerBean.java:813)

at com/kingdee/eas/base/dap/app/DAPTransformerControllerBean._generateVoucher(DAPTransformerControllerBean.java:649)

at com/kingdee/eas/scm/common/app/SCMBillBaseControllerBean._generateVoucher(SCMBillBaseControllerBean.java:1057)

 

通过线程堆栈可以看出:调拔入库单生成凭证内存占用过大,导致溢出宕机

 

附录2:如何切换EAS的运行时环境?

eas\server\profiles\server*\bin目录下,找到set-server-env.bat(sh)文件。将JAVA_HOME变量的值设置为imbjdk的路径。如果找不到JAVA_HOME这个变量,请直接添加。如下图:

你可能感兴趣的:(EAS服务器内存溢出、宕机解决方案-Heapdump与JavaCore分析)