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

Gre*_*her 12 java memory-management out-of-memory

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

我们当前所做的事情:我们现在entry count在数据集中估算memory to be usedas entry count * empirical factor(手动确定).然后检查它是否低于空闲内存(得到Runtime.freeMemory()),如果是,则加载它(否则重做其他节点上的进程/报告没有空闲容量).

这种方法的问题是:

  • empirical factor需要被重新和手动更新
  • freeMemory有时可能会因为一些未清理的垃圾而少报(这可以通过System.gc在每次这样的通话之前运行来避免,但这会减慢服务器的速度并且还可能导致过早的促销)
  • 另一种方法是"只是尝试加载数据集"(如果抛出OOM则返回)但是一旦抛出OOM,你可能会破坏在同一个JVM中运行的其他线程,并且没有优雅的方法从中恢复.

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

Pet*_*rey 1

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

虽然freeMemory()几乎总是小于 GC 后可用的数量,但您可以检查它是否可用,并在指示可能有足够的情况System.gc()下调用 a 。maxMemory()

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

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