gpt4 book ai didi

java - 基于容错的方法来避免 java.lang.OutOfMemoryError

转载 作者:行者123 更新时间:2023-11-29 05:54:37 25 4
gpt4 key购买 nike

许多精心设计的 Java 代码都被 java.lang.OutOfMemoryError 浪费了。似乎没有任何缓解,甚至生产类代码也被它搞垮了。

我想问的问题是:是否有良好的编程/架构实践可以避免遇到此错误。

因此 Java 程序员可以使用的工具似乎是:

  1. java.lang.Runtime.addShutdownHook(Thread hook) -- 关闭 Hook 允许优雅地下降。
  2. java.lang.Runtime.freeMemory() -- 允许我们检查 VM 可用的内存

所以我的想法是:是否可以编写工厂方法,在创建对象之前检查系统是否有足够的剩余内存,然后再尝试分配内存?例如,在 C 语言中,malloc 会失败,您会知道内存已用完,这不是理想情况,但您不会因 java.lang.OutOfMemoryError 动脉瘤而死。

建议的方法是进行更好的内存管理或堵塞内存泄漏或简单地分配更多内存——我同意这些都是有值(value)的观点,但让我们看看以下场景:

  1. 我在亚马逊微型实例上运行
  2. 我可以为我的 VM 分配很少的内存,比如 400M
  3. 我的 Java 进程以多线程方式处理作业,每个线程根据计算任务的参数消耗可变数量的内存
  4. 假设我的进程没有内存泄漏
  5. 现在,如果我在任务完成之前继续给它喂食,它最终会死于内存不足
  6. 如果我将 -Xmx 设置得太高——我将进行交换并可能在操作系统上颠簸
  7. 如果我设置并发上限 - 这可能不是最优的,因为我可能会限制接受一个可以使用可用 RAM 执行的作业,或者更糟的是接受一个需要大量内存并最终命中的作业java.lang.OutOfMemoryError 无论如何。X. 希望这有助于解释问题的动机——我认为标准回答与寻求容错方法解决问题并不相互排斥。

提前致谢。

最佳答案

我们更多地将 JVM 内存作为调整参数来处理,而不是作为应用程序主动管理的东西。我们有一个 MemoryInfo 类(它包装了几个运行时内存信息方法)。

当应用程序运行时,我们跟踪应用程序中的空闲内存:

 Runtime.getMaxMemory() - Runtime.getTotalMemory() + Runtime.getFreeMemory();

最大内存是 -Xmx jvm arg,总内存是 JVM 已经分配给应用程序堆的内存,空闲内存是分配的堆内存中仍有多少可用。 (如果您的 -Xms 参数与您的 -Xmx 参数相同,那么 getFreeMemory() 就是您需要检查的全部)。

如果内存使用率超过 70%,我们会向监控系统发送警报。那时我们决定是否可以一瘸一拐地度过当天剩下的时间,或者是否调整 -Xmx 参数并重新启动。虽然这看起来有点困惑,但在实践中,一旦我们调整了一个系统,我们再也不会在那之后遇到内存问题。 (一旦您使用的最大内存超过 90%,JVM 将极其频繁地进行 GC 以尝试防止内存不足)。

我认为在每个构造中管理内存的方法是严厉的,但如果你需要绝对控制,那么它也许是有意义的。另一种方法是确保您使用的任何内存缓存都具有 LRU 或过期和重新加载机制,因此您可以更好地限制内存中保留的对象数量。

也就是说,我们的方法是尽可能多地保留在内存中,并分配足够的 RAM。我们的大型系统分配了 28G RAM(我们平均使用了其中的 40-60%)。

关于java - 基于容错的方法来避免 java.lang.OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12630730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com