java.lang.OutOfMemoryError已经浪费了许多精心设计的Java代码。似乎没有任何缓解,甚至生产类代码也被它击落。
我想问的问题是:是否有良好的编程/架构实践,您可以避免遇到此错误。
因此,Java程序员处理的工具似乎是:
所以我的想法是:可以在创建对象之前编写工厂方法,在尝试分配内存之前检查系统是否有足够的内存吗?例如在C语言中,malloc会失败并且你会知道你的内存耗尽,这不是一个理想的情况,但你不会从java.lang.OutOfMemoryError动作中消失。
建议的方法是更好的内存管理或插入内存泄漏或只是分配更多内存 - 我同意这些是有价值的观点,但让我们看看以下场景:
提前致谢。
答案 0 :(得分:2)
我们更多地将JVM内存作为调整参数处理,而不是像应用程序那样主动管理。我们有一个MemoryInfo类(它包含了几个Runtime内存信息方法)。
在应用程序运行时,我们会在应用程序中跟踪可用内存:
Runtime.getMaxMemory() - Runtime.getTotalMemory() + Runtime.getFreeMemory();
最大内存是-Xmx jvm arg,总内存是JVM已经分配给应用程序堆的内存,可用内存是分配的堆内存仍然可用的数量。 (如果您的-Xms参数与-Xmx参数相同,那么您需要检查getFreeMemory()
。)
如果我们的内存使用量超过70%,我们会向监控系统发送警报。在那时,我们决定是否可以在当天的剩余时间里跛行,或者是否调整-Xmx参数并重新启动。虽然这看起来有点混乱,但实际上,一旦我们调整了系统,我们永远不会在此之后遇到内存问题。 (一旦你使用了超过90%的最大内存,JVM将非常频繁地尝试GC以防止内存不足。)
我认为在每种结构中管理内存的方法都很简单,但如果你需要绝对控制,那么也许它是有道理的。另一种方法是确保您使用的任何内存缓存都具有LRU或Expiration and reload机制,这样您就可以更好地限制内存中保留的对象数。
那就是说,我们的方法是尽可能地保留在内存中,并且只需分配足够的RAM。我们的大系统分配了28G RAM(我们平均使用40-60%)。
答案 1 :(得分:1)
好的,正如我之前所建议的那样,解决方案是需要更少的内存。运行无限量的线程没有意义,因为您的进程会收到多个请求。限制每个进程中的线程数,并且最多同时处理该数量的请求。其余的请求只会等待。
由于你没有无限数量的核心,无论如何,太多线程都是个坏主意。