System.gc()由核心API调用

你们中的一些人可能知道一些核心java API会对System.gc()进行显式调用。 发生这种情况时我知道两种情况:

  1. NIO。 我相信,当系统耗尽“直接”内存时,可以对直接ByteBuffers进行一些清理。
  2. RMI。 在这里,原因对我来说并不清楚……

所以,问题是:

  1. 知道为什么RMI需要System.gc()吗?
  2. 当核心API(甚至其他一些流行的库)可以直接调用System.gc()时,您是否知道其他任何情况?

如果存在需要清理的分布式对象,RMI会调用System.gc()。 您可以减少频繁执行GC或有效关闭GC。

您可以通过调用避免直接ByteBuffer需要GC在Sun / Oracle JVM上清理它们

 ByteBuffer bb = ByteBuffer.allocateDirect(SIZE); ((DirectBuffer) bb).cleaner().clean(); 

我不明白为什么他们甚至暴露了gc()方法。 即使在文档中,Java也很清楚这种行为是不可预测的。 医生说

“调用gc方法表明Java虚拟机花费了很多精力来回收未使用的对象”

意思是,它可以做任何事情,包括什么都没有。

至于问题,许多应用程序服务器在这里和那里调用System.gc()。 WebSphere是一个主要攻击者,您可以在WAS / Portal代码库中找到它。 在我能记住的开源库/框架中没有看到它。 可能致力于为这些框架做出贡献的人有足够的意识,不使用具有不确定行为的操作。

我的猜测是,当开发人员认为“在某些情况下,此操作可能会在处理中使用大量”临时“(短期)内存时,它会被调用,所以我会做一些垃圾收集来回收它”。 这也可能是您的RMI场景的情况。 在我看来,这是假的。 在某些情况下,调用System.gc()可以通过过早(并且不必要地)触发完整的GC循环来降低性能。 重点是,垃圾收集器非常聪明,除非你确定你知道的更好,否则不要试图搞砸它。

JDK实现确切知道它自己的System.gc()行为方式。 JDK不必假装是不可知的,将自己限制在标准抽象行为,而不是具体的专有行为(当然符合标准行为)

是的,它可以调用System.gc()因为它认为合适。 我们不应该。