leak(二)netty java 11与监控
0 为什么used不好用
PlatformDependent.usedDirectMemory始终返回-1
跟踪下来,io.netty.util.internal.PlatformDependent0#hasDirectBufferNoCleanerConstructor始终返回false
关于 mxbean
https://segmentfault.com/a/1190000044509636
因此netty所分配的直接内存大小,常规的监控手段无法监测,包括arthas、visualvm中的MBean、以及其他所有通过jmx获取直接内存数据的手段。mbean基于Bits,netty不基于
如果要监控,只能自定义实现,从PlatformDependent
入手,网上已有不少资料。
关于 -XX:NativeMemoryTracking=detail
jcmd $pid VM.native_memory detail
懒得尝试
1
public static byte[] allocateUninitializedArray(int size) {
return UNINITIALIZED_ARRAY_ALLOCATION_THRESHOLD >= 0 && UNINITIALIZED_ARRAY_ALLOCATION_THRESHOLD <= size ? PlatformDependent0.allocateUninitializedArray(size) : new byte[size];
}
先关注到了这里,有没有可能后来用jvm内存得?
debug
发现UNINITIALIZED_ARRAY_ALLOCATION_THRESHOLD=-1,为什么:
int tryAllocateUninitializedArray = SystemPropertyUtil.getInt("io.netty.uninitializedArrayAllocationThreshold", 1024);
UNINITIALIZED_ARRAY_ALLOCATION_THRESHOLD = javaVersion() >= 9 && PlatformDependent0.hasAllocateArrayMethod() ? tryAllocateUninitializedArray : -1;
logger.debug("-Dio.netty.uninitializedArrayAllocationThreshold: {}", UNINITIALIZED_ARRAY_ALLOCATION_THRESHOLD);
static boolean hasAllocateArrayMethod() {
return ALLOCATE_ARRAY_METHOD != null;
}
class io.netty.util.internal.PlatformDependent0$7 cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module @6d3a9b8b
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED --illegal-access=warn
增加-Dio.netty.uninitializedArrayAllocationThreshold=1,再debug
2
确实走后门那个方法了,而不是new byte[],但是还是没压跨掉
3 再回到io.netty.util.internal.PlatformDependent0#hasDirectBufferNoCleanerConstructor始终返回false,既然io.netty.util.internal.PlatformDependent#usedDirectMemory返回-1,就表示没有用直接内存?
试试看
io.netty.util.internal.PlatformDependent0#DIRECT_BUFFER_CONSTRUCTOR 这个为什么一直是null
java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled
报错,增加
-Dio.netty.tryReflectionSetAccessible=true
成功压垮
参考:
https://www.jianshu.com/p/c915aced3396
还是建议大家在使用jdk9以上的时候,把这个参数打开。
https://zhuanlan.zhihu.com/p/654366685
jdk17 下 netty 导致堆内存疯涨原因排查 | 京东云技术团队
4 -Dio.netty.uninitializedArrayAllocationThreshold=100000
还是垮掉了
删除1中的两个config,一样
-XX:MaxDirectMemorySize=100k
-Dio.netty.tryReflectionSetAccessible=true