由核心API进行的System.gc()调用

问题描述 投票:12回答:4

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

  1. NIO。我相信这样做是为了在系统耗尽“直接”内存时对直接ByteBuffer进行一些清理。
  2. RMI。在这里,原因对我来说还不清楚...

所以,问题是:

  1. 知道RMI为何需要System.gc()的原因吗?
  2. 您知道核心API(甚至其他流行的库)可以直接调用System.gc()的任何其他情况吗?
java garbage-collection jvm
4个回答
5
投票

RMI在有需要清理的分布式对象的情况下调用System.gc()。您可以使其执行GC的频率降低或有效地将其关闭。

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

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

2
投票

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

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

意思是,它可以做很多事情,什么都不做。

关于这个问题,很多应用服务器在这里和那里都调用System.gc()。 WebSphere是主要的冒犯者,您可以在WAS / Portal代码库中找到它。我还记得在开源库/框架中没有看到它。可能为这些框架做出贡献的人们有足够的意识,不要使用行为无法定义的操作。

我的猜测是,当开发人员认为“此操作在某些情况下可能会在处理中使用大量”临时”(短暂的)内存时,就会调用它,因此我将进行一些垃圾回收以回收”。您的RMI方案也可能是这种情况。我认为这是假的。在某些情况下,调用System.gc()可能会过早(不必要)触发完整的GC周期,从而降低性能。重要的是,垃圾收集器非常聪明,除非您确定自己了解得更多,否则请勿尝试弄乱它。


1
投票

JDK实现确切知道其自己的System.gc()的行为。 JDK不必假装是不可知论者,可以将自己约束为标准的抽象行为,而不是具体的专有行为(当然符合标准行为)

是,它可以根据需要调用System.gc()。我们不应该。


0
投票

因此,搜索您的应用程序代码“ System.gc()”字符串不足以判断您的应用程序是否在进行System.gc()调用。因此,这构成了一个挑战:如何检测是否在整个应用程序堆栈中调用了System.gc()调用?

这是GC日志很方便的地方。您的应用程序中的Enable GC logs。实际上,建议您始终在所有生产服务器中始终启用GC日志,因为它可以帮助您排除故障并优化应用程序性能。启用GC日志会增加微不足道的开销(如果可以观察到的话)。现在,将您的GC日志上传到垃圾收集日志分析器工具,例如GCeasy,HP JMeter等。这些工具可生成丰富的垃圾收集分析报告。

Read More here...

© www.soinside.com 2019 - 2024. All rights reserved.