在我的公司,我们正在尝试一种使用基于 JVM 的微服务的方法。它们被设计为水平扩展,因此我们使用相当小的容器(最多 2G 堆,通常为 1-1.5G)运行每个实例的多个实例。我们使用的 JVM 是 1.8.0_40-b25。
每个此类实例通常处理高达 100 RPS,最大内存分配速率约为 250 MB/s。
问题是:什么样的 GC 是安全合理的默认设置?到目前为止,我们正在使用 Xms = Xmx(以避免在调整堆大小期间暂停)和 Xms = Xmx = 1.5G 的 CMS。结果不错——我们几乎没有看到任何 Major GC 执行。
我知道 G1 可以给我更小的暂停(以总吞吐量为代价)但据我所知,它需要更多的“呼吸”空间和至少 3-4G 堆才能正常执行。
有什么提示(除了 Azul 的 Zing :D 之外)?
最佳答案
提示 # 1:做实验!
假设您的微服务至少部署在两个节点上,一个在 CMS 上运行,另一个在 G1 上运行,然后查看响应时间。
不太可能,但是如果您发现 G1 性能非常好以至于需要原始集群大小的一半怎么办?
旁注:
- re: "250Mb/s"-> 如果所有这些都是堆栈内存(或者,如果它是年轻一代)那么 G1 将提供很少的好处,因为从这些区域收集是免费的。
- re: "100 RPS"-> 在我们生产的许多情况下,我们发现减少系统中的并发请求(通过代理配置或在应用程序容器级别)可以提高吞吐量。鉴于小堆,很可能您的 cpu 数量也很小(2 到 4)。
- 此外还有官方 Oracle 提示 on tuning for a small memory footprint .它可能无法反射(reflect) 1.8_40 上可用的最新配置,但无论如何都值得一读。
关于java - 具有小堆的微服务的明智 Xmx/GC 默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36676832/