java - 手动 GC 调用的用例?

标签 java performance garbage-collection failover

我已阅读 why is it bad practice to call System.gc() ,以及许多其他的,例如this one描述了对 System.gc() 的一次真正灾难性的滥用。然而,在某些情况下,GC takes too long并避免长时间停顿,例如 avoiding garbage这并不完全是微不足道的,并且使代码更难维护。

恕我直言,在以下常见场景中手动调用 GC 是可以的:

  • 有多个可互换的网络服务器,它们前面有故障转移。
  • 每台服务器都使用几 GB 的堆,STW 暂停时间比平均请求长得多。
  • 故障转移不知道 GC 何时发生。
  • 故障转移可以根据需要免除服务器的责任。

该算法似乎很简单:定期选择一个服务器,不再向其发送任何请求,让它完成正在运行的请求,让它执行 GC,然后重新激活该服务器。

我想知道我是否遗漏了什么?1,2

有哪些替代方案?

  1. 长时间运行的请求可能是一个问题,但我们假设没有问题。或者简单地将等待时间限制为与 GC 所需时间相当的时间。发出更慢的请求听起来还不错。

  2. -XX:+DisableExplicitGC 这样的选项可能会使算法变得无用,但不要使用它(我的用例包括我负责的专用服务器)。

最佳答案

对于低延迟交易系统,我以非典型方式使用 GC。

您希望避免在交易日期间发生任何收款,即使是轻微的收款。实现此目的的一种方法是每秒创建少于 300 KB 的垃圾。这大约是每小时 1 GB,或每天最多 24 GB。当您使用 24 GB Eden 空间时,这意味着没有次要/主要 GC。然而,为了确保 GC 在计划且可接受的时间发生,System.gc()比如每天早上 5 点接到电话,第二天您就有一个干净的伊甸园空间。

有时,您创建的垃圾比预期多,例如无法重新连接到数据源,并且您可能会获得少量的次要集合。然而,只有当出现问题时才会发生这种情况。

了解更多详情http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html

by avoiding garbage is not exactly trivial and makes the code harder to maintain.

完全避免垃圾几乎是不可能的。然而 300 KB/s 对于 JVM 来说并不是那么困难。 (如今,您可以在一台具有 24 GB Eden 空间的机器上拥有多个 JVM)

请注意,如果您能够将垃圾速度保持在 50 KB/s 以下,您就可以在没有 GC 的情况下运行一整周。

Periodically select a server, let no more requests be send to it, let it finished its running requests, let it do its GC, and re-activate the server.

您可以将 GC 视为未能满足 SLA 条件。在这种情况下,当您确定集群即将发生这种情况时,您可以删除服务器,对其进行 Full GC 并将其返回到集群。

关于java - 手动 GC 调用的用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36962630/

相关文章:

java - 类转换异常 : Fragment1 cannot be cast to Fragment2

gdi+ Graphics::DrawImage 真的很慢~~

multithreading - CFThread GC开销限制已达到的问题

c# - 一段时间后 GC 包含大量固定对象

java - 在 Java 中重写方法而不进行子类化

java - 在框架外显示元素

performance - 我们如何衡量 HTTP/2 header 压缩带来的性能改进

asp.net - 通过缓存、ThreadStatic 等降低 ASP.NET 中的初始化频率

python - 为什么 "del x"不会改变生成器的结果而 x.append 会改变?

java - 从 Jersey/JAX-RS 客户端将 ZIP 发布到 Artifactory