WAS典型故障案例:DirectByteBuffer占用本地内存高

故障现象

 

 

java 进程(PID:21889322) 的CPU 以及内存使用率突然增高,随后 CPU 恢复正常,但是内存一直保持较高状态。CPU 最高达到 34%,内存最高占用 17G。

 

 

分析过程

 

 

WAS 版本为:8.0.0.6,OS 版本为:AIX6.1

通过javacore.20151208.112729.21889332.0001.txt 查看内存状态,整个 JVM 占用内存大概 12G,其中堆内存占用 3G,本地堆内存占用高达 9G 左右;而其中DirectByteBuffer 占用为 8G。因此判断主要问题在于DirectByteBuffer 占用本地内存偏高,并且使用后长时间没有释放。

 

1MEMUSER     JRE: 12,641,858,008 bytes / 803964 allocations

……

5MEMUSER| | | +--Direct Byte Buffers: 8,443,918,272 bytes / 683183 allocations

 

判断应用执行了类似 Download Log 的操作,该操作需要向WAS 申请Buffer 便于输出流操作,由于WAS 使用的 NIO( 异步 IO) 模式, 因此申请 Buffer 使用的是DirectByteBuffer 的模式。DBB 的特点是:使用本地堆内存,但是他的回收机制是通过对象虚引用,使用 java 堆的 gc 方式回收内存。并且 DirectByteBuffer 是需要进行system.gc() 来实现清理工作的。

 

 

解决方案

 

 

◆去掉 WAS 的 JVM 参数 -Xdisableexplicitgc, 该参数会禁用掉所有 system.gc() 的操作。

 

◆使用 -XX:MaxDirectMemorySize=$bytes 参数, 控制 DirectByteBuffer 的数量。

 

◆将 WebContainer channelwritetype 的值改为async。


锻造凝炼IT草莓视频黄色在线观看 助推用户事业发展
地址:北京市西城区百万庄大街11号粮科大厦3层
电话:(010)58523737
传真:(010)58523739