- 对外内存监控示例
- 设置
-XX:-+DisableExplicitGC 限制堆外内存大小 如果没有设置默认上限和 -Xmx 大小一致 堆外内存不够将触发full gc回收堆内对象,有引用堆外内存的对象被回收后触发finalize回收堆外内存 或者触发cleaner回收。 - 堆外内存查看 MBeanServer获取
MBeanServer mbs = ManagementFactory. getPlatformMBeanServer() ; ObjectName objectName = new ObjectName("java.nio:type=BufferPool,name=direct" ) ; MBeanInfo info = mbs.getMBeanInfo(objectName) ; for(MBeanAttributeInfo i : info.getAttributes()) { System.out .println(i.getName() + ":" + mbs.getAttribute(objectName , i.getName())); }
gc dump 获取 配合pmap 查看指向内存的引用对象
-
JDK 获取堆外内存使用情况 /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/src.zip!/java/nio/Bits.java:730
// -- Monitoring of direct buffer usage -- static { // setup access to this package in SharedSecrets sun.misc.SharedSecrets.setJavaNioAccess( new sun.misc.JavaNioAccess() { @Override public sun.misc.JavaNioAccess.BufferPool getDirectBufferPool() { return new sun.misc.JavaNioAccess.BufferPool() { @Override public String getName() { return "direct"; } @Override public long getCount() { return Bits.count.get(); } @Override public long getTotalCapacity() { return Bits.totalCapacity.get(); } @Override public long getMemoryUsed() { return Bits.reservedMemory.get(); } }; } @Override public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) { return new DirectByteBuffer(addr, cap, ob); } @Override public void truncate(Buffer buf) { buf.truncate(); } }); }
- 定位
通过NMT pmap定位到是GZIPInputStream 没有close导致的堆外内存持续增加。可能引发 堆外内存不够用 持续full gc、或者swap占用等