我有一个应用程序,其后端基于Java 8构建。最近,由于OOM,我已经看到应用程序自行重启。我通过查看Docker Container的退出状态来了解它是因为OOM。没有为系统配置Xmx
和Xms
值,因此它应该使用默认堆大小,如果我的服务器有4 GB内存应该是大约512 MB(我读取一些SO答案,即deafult heap max size是存在的内存的1/8)。设置Xms
和Xmx
值后,我的应用现在无需重启即可正常运行。在设置Xmx
和Xms
值之前,我还尝试将服务器中的内存增加到7场演出,但它也没有帮助。我想知道的是,当应用程序有足够的可用内存时,系统如何运行OOM
如果应用程序的内存需求增加,默认堆大小是否会自行扩展?如果内存满了,为什么GC没有被触发?
答案 0 :(得分:3)
如果内存要求,默认堆大小是否会自行扩展 应用增加了吗?
是的,但最多只能达到-Xmx
中的值(或JVM选择的该值的默认值)。
如果内存满了,为什么GC没有被触发?
GC被触发,但它无法收集任何垃圾。堆中的所有东西都是非垃圾。
答案 1 :(得分:2)
“当有足够的记忆时,系统如何进行OOM 可用于该应用程序。“
这里有两个可能的问题:
您还没有为应用程序的内存需求配置足够的内存,那么您可以共享配置的值吗?
应用程序导致内存泄漏问题,因此您应该记住这一点
来源:http://blog.sysco.no/memory/leak/memory-leak/
Java的一个主要优点是使用垃圾收集器 这让程序员忘记了内存管理。那是 不是你必须分配的C ++等语言的情况 自代码以来的可用内存。根据我在一家大公司的经历,我看到了 内存泄漏问题多次导致不可用或 许多应用程序的性能不佳。
此外,内存泄漏属于一类被称为的情境 软件老化问题。软件老化定义了损失 随着时间的推移,表现逐渐积累 小问题。这类问题中的其他术语是 复兴过程。例如,当复兴时发生 系统必须重新启动才能释放累积的内存 一段时间后的Java虚拟机(JVM)进程(COTRONEO, D,et al。,2015)。
基本上,JVM上的垃圾收集器使用一种机制来重用对象的空间,这些机制没有来自根集的任何引用,因此当源代码或配置中存在一个问题时,对象始终保持引用,很少应用程序将逐渐填满堆,直到达到其极限。
例如,在下图中,只会收集图中的无法访问的对象,所有可访问的对象(即使是由错误或错误配置生成的对象)将保留在堆中
来源http://blog.sysco.no/files/guides/JVMGarbageCollectionV1.1.pdf
“如果内存要求,默认堆大小是否会自行扩展 应用程序的增加?“
答案不是,当tyour应用程序填满整个新一代时,JVM将执行一个次要的GC来释放新一代的对象,那些幸存者会被移入幸存者空间一段时间,直到他们达到某个年龄。当它们(幸存者空间中的物体)足够成熟并且仍然存活时,这些物体被提升到老一代,当旧一代充满时,执行完整的GC。因此,因为您的应用程序似乎在某个时刻保留引用(内存泄漏),整个堆将填充活动对象,因此JVM无法释放它们,并且它没有标志来增加内存的情况像这样。
“如果内存满了,为什么GC没有被触发?”
在这种情况下,我有一个问题,您如何知道GC是否被触发?要调整垃圾收集过程,您必须对此进行测量,以便您可以尝试使用这些标志来获取有关GC执行的信息。
-XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps -Xloggc:/home/user666/gc.log
此外,您可以使用这个漂亮的网络来分析日志文件
Las但并非最不重要,你可以使用这些标志
-XX:+ HeapDumpOnOutOfMemoryError -XX:HeapDumpPath = / some / where / your / machine
使用这些标志,您将生成堆转储,可以使用Memory Analyzer Tool(MAT:https://www.eclipse.org/mat/downloads.php)进行分析,以确定应用程序是否存在内存泄漏。
答案 2 :(得分:1)
默认的最大堆大小是主内存的1/4。这假设机器不专用于这一个过程。如果是,您可能希望增加最大堆大小。
注意:堆大小只是堆的大小,它只是JVM使用的一个内存区域。 不总内存消耗量。 JVM需要多少额外内存取决于它正在做什么。
初始大小可以增长到最大值。最大的大小不会增长,它是您希望进程死的堆的大小而不是使用的大小。
如果没有更多信息,我会尝试在4 GB计算机上运行3 GB堆,如果它正在运行并看看它是如何运行的。您可以在top
注意:并非所有OutOfMemoryError都相同,您需要阅读错误消息以确定问题的实际原因。例如你可能已经用完了线程,perm gen / metaspace或其他一些低级内存问题。