官方文档:
http://www-01.ibm.com/support/docview.wss?rs=180&uid=swg21236523
问题
当您进行分析Java Heap内存碎片和内存泄漏问题时,经常会发现大对象内存频繁申请,会直接导致应用服务器的崩溃。那么我们如何来定位由哪个应用模块的哪个Class类的哪个方法直接导致大对象的产生,从而导致服务器宕机?
解决方案
自从IBM SDK 1.3.1 Sovereign Service Release 10 以后的版本 (或构建日期2006年5月5日以后) 和 IBM SDK 1.4.2 Sovereign Service Release 4以后的版本,我们可以设置环境变量ALLOCATION_THRESHOLD 来定义内存申请的上限值。
如果内存对象申请的大小超过此上限,Java虚拟机会自动打印出类似与Java Exception 异常堆栈日志信息的类方法诊断信息,来定位到底是由哪个对象的哪个方法向内存申请了大对象空间。
输出日志类似:
Allocation request for bytes
at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)
at org.apache.xerces.impl.XMLEntityScanner.skipString(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.batik.dom.util.SAXDocumentFactory.createDocument(Unknown Source)
如果您把ALLOCATION_THRESHOLD环境变量设置为nnn (bytes), 一旦应用申请对象的大小大于nnn (bytes)时, 当前运行线程的Java类方法调用级联堆栈信息就会自动打印到native_stderr.log日志文件中了。
比如以下测试案例代码:
import java.io.*;
public class largeobj {
static int limit = 20;
static int size1 = 1000000;
static int size2 =2*size1;
public static void main(String []args) throws IOException {
for (int index0=0; true; index0++) {
if (0 == index0 % 100) System.out.println(index0);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(String.class);
oos.close();
Object array1 = null;
for(int i1=0; i1 System.out.println("" + i1);
array1 = new Object ;
for (int i2=0; i2 array1 = new Object;
}
}
array1=null;
}
}
}
如果您把JVM运行的环境变量设置如下:
export ALLOCATION_THRESHOLD=5000000
当申请对象的大小超过设定的上限值时,那您会获得以下打印日志信息:
Allocation request for 8000016 bytes
at largeobj.main(largeobj.java:18)
同样您也可以在WebSphere Application Server V5.1.1 and V6.0以后的版本中,设置ALLOCATION_THRESHOLD环境变量。
关于如何在WebSphere Application Server V5.1.1 and V6.0以后版本的服务器中设置ALLOCATION_THRESHOLD环境变量,请参考以下步骤:
WebSphere Application Server 6.0
可以通过在WebSphere Application Server versions 6.0 and 6.0.1的管理控制台中,按照以下步骤加入对应的环境变量:
1、 打开WebSphere Web管理控制台。
2、选择 Servers > Application Servers > server_name > Java and Process Management > Process Definition > Environment Entries > New.
3、 如果您使用WebSphere Application Server 6.0.2以后的版本, 按照如下顺序选择进入: Application servers > server_name > (Expand Java and Process Management) > Process Definition > Custom Properties
4、 增加以下名称和对应的值:
Name: ALLOCATION_THRESHOLD
Value: value
5、 最后确认新增配置的保存,再重新启动应用服务器。
WebSphere Application Server 5.1.1
可以通过在WebSphere Application Server versions 5.1.1的管理控制台中,按照以下步骤加入对应的环境变量:
1、 打开WebSphere Web管理控制台。
2、 选择 Servers > Application Servers > server_name > Process Definition > Environment Entries > New.
3、 增加以下名称和对应的值:
Name: ALLOCATION_THRESHOLD
Value: value
4、 最后确认新增配置的保存,再重新启动应用服务器。