如何估计JVM是否有足够的可用内存用于特定的数据结构?

2022-09-04 23:11:34

我有以下情况:有几台机器形成一个集群。客户端可以加载数据集,我们需要选择将加载数据集的节点,如果没有一台机器可以容纳数据集,则拒绝加载/避免OOM错误。

我们目前做什么:我们现在在数据集中并估计为(手动确定)。然后检查这是否低于可用内存(已获得),如果是,则加载它(否则在其他节点上重做该过程/报告没有可用容量)。entry countmemory to be usedentry count * empirical factorRuntime.freeMemory()

这种方法的问题在于:

  • 需要手动重新访问和更新empirical factor
  • freeMemory有时可能会因为一些未清理的垃圾而漏报(这可以通过在每次此类调用之前运行来避免,但是这会减慢服务器的速度,并且还可能导致过早升级)System.gc
  • 另一种方法是“只是尝试加载数据集”(如果抛出OOM,则退出),但是一旦抛出OOM,您可能会损坏在同一JVM中运行的其他线程,并且没有从中恢复的优雅方法。

有没有更好的解决方案来解决这个问题?


答案 1

可以计算为构建步骤并放置在属性文件中。empirical factor

虽然几乎总是小于GC后的免费金额,但您可以检查它以查看它是否可用,并调用a,如果指示可能有很多。freeMemory()System.gc()maxMemory()

注意:在生产中使用只会在非常罕见的情况下使用,并且通常经常错误地使用它,从而导致性能降低并掩盖真正的问题。System.gc()

我会避免触发OOME,除非您运行的是可以根据需要重新启动的JVM。


答案 2

我的解决方案:

  1. 将Xmx设置为物理机的RAM,如果除了您的程序之外没有其他进程正在运行。对于 32 GB RAM 计算机,设置为 。90%-95%Xmx27MB - 28MB

  2. 使用良好的gc算法之一 - CMSG1GC并微调相关参数。.如果您选择 G1GC,请参考以下问题:I prefer G1GC if you need more than 4 GB RAM for your application

    攻击性垃圾回收器策略

    使用 UseConcMarkSweepGC 将 JVM 暂停时间> 1 秒

  3. 自行计算内存使用量上限,而不是检查可用内存。添加已用内存和要分配的内存。.如果仍有可用内存,请授予内存分配请求。Subtract it from your own cap like 90% of Xmx


推荐