我一直在努力解决同样的问题,根据我能够找到的所有信息,这肯定存在一些风险。根据 @millimoose 和 https://bugs.openjdk.java.net/browse/JDK-6200079 的原始帖子中的 cmets,如果使用 NIO 直接缓冲区,设置 -XX:+DisableExplicitGC 似乎不是一个好主意。看来它们正在我们正在使用的 Websphere 8.5 应用服务器的内部实现中使用。这是我在调试时能够捕获的堆栈跟踪:
3XMTHREADINFO "WebContainer : 25" J9VMThread:0x0000000006FC5D00, j9thread_t:0x00007F60E41753E0, java/lang/Thread:0x000000060B735590, state:R, prio=5
3XMJAVALTHREAD (java/lang/Thread getId:0xFE, isDaemon:true)
3XMTHREADINFO1 (native thread ID:0x1039, native priority:0x5, native policy:UNKNOWN)
3XMTHREADINFO2 (native stack address range from:0x00007F6067621000, to:0x00007F6067662000, size:0x41000)
3XMCPUTIME CPU usage total: 80.222215853 secs
3XMHEAPALLOC Heap bytes allocated since last GC cycle=1594568 (0x1854C8)
3XMTHREADINFO3 Java callstack:
4XESTACKTRACE at java/lang/System.gc(System.java:329)
4XESTACKTRACE at java/nio/Bits.syncReserveMemory(Bits.java:721)
5XESTACKTRACE (entered lock: java/nio/Bits@0x000000060000B690, entry count: 1)
4XESTACKTRACE at java/nio/Bits.reserveMemory(Bits.java:766(Compiled Code))
4XESTACKTRACE at java/nio/DirectByteBuffer.<init>(DirectByteBuffer.java:123(Compiled Code))
4XESTACKTRACE at java/nio/ByteBuffer.allocateDirect(ByteBuffer.java:306(Compiled Code))
4XESTACKTRACE at com/ibm/ws/buffermgmt/impl/WsByteBufferPoolManagerImpl.allocateBufferDirect(WsByteBufferPoolManagerImpl.java:706(Compiled Code))
4XESTACKTRACE at com/ibm/ws/buffermgmt/impl/WsByteBufferPoolManagerImpl.allocateCommon(WsByteBufferPoolManagerImpl.java:612(Compiled Code))
4XESTACKTRACE at com/ibm/ws/buffermgmt/impl/WsByteBufferPoolManagerImpl.allocateDirect(WsByteBufferPoolManagerImpl.java:527(Compiled Code))
4XESTACKTRACE at com/ibm/io/async/ResultHandler.runEventProcessingLoop(ResultHandler.java:507(Compiled Code))
4XESTACKTRACE at com/ibm/io/async/ResultHandler$2.run(ResultHandler.java:905(Compiled Code))
4XESTACKTRACE at com/ibm/ws/util/ThreadPool$Worker.run(ThreadPool.java:1864(Compiled Code))
3XMTHREADINFO3 Native callstack:
4XENATIVESTACK (0x00007F61083DD122 [libj9prt26.so+0x13122])
4XENATIVESTACK (0x00007F61083EA79F [libj9prt26.so+0x2079f])
....
在使用 NIO 直接字节缓冲区时设置 -XX:+DisableExplicitGC 的全部后果对我来说还不是很清楚(这是否会导致内存泄漏?),但至少看起来确实如此那里有一些风险。如果您使用的是 Websphere 以外的应用服务器,您可能需要在禁用它之前验证应用服务器本身没有通过 NIO 调用 System.gc()。我有一个相关的问题,希望能在此处获得对 NIO 库的确切影响的一些澄清:Impact of setting -XX:+DisableExplicitGC when NIO direct buffers are used
顺便说一下,Websphere 在启动过程中似乎也多次手动调用 System.gc(),通常在应用服务器启动后的前几秒钟内调用两次,在前 1-2 分钟内调用第三次(可能部署应用程序时)。在我们的案例中,这就是我们首先开始调查的原因,因为似乎所有 System.gc() 调用都直接来自应用服务器,而不是来自我们的应用程序代码。
还需要注意的是,除了NIO库之外,RMI分布式垃圾回收的JDK内部实现也调用了System.gc():
Unexplained System.gc() calls due to Remote Method Invocation
System.gc() calls by core APIs
启用 -XX:+DisableExplicitGC 是否也会对 RMI DGC 造成严重破坏,我也有点不清楚。我能找到的唯一参考,甚至解决了这个问题是上面的第一个参考,它指出
“但是,在大多数情况下,定期的 GC 活动就足够了
有效的 DGC"
“在大多数情况下”限定符对我来说听起来非常不切实际,所以再一次,似乎至少有一些风险只是关闭所有 System.gc() 调用,你最好修复尽可能在您的代码中调用,并且仅在万不得已的情况下完全关闭它们。