[英]Default Java Heap Size and Memory Issues it can cause
我有一个应用程序,其后端基于Java 8构建。最近,我发现由于OOM,应用程序会自行重新启动。 通过查看Docker容器的退出状态,我了解了它是由于OOM而引起的。 没有为系统配置Xmx
和Xms
值,因此它应该使用默认堆大小,如果我的服务器有4个内存,则该大小应约为512 MB(我读了一些默认的堆大小的答案最大大小是当前内存的1/8)。 设置Xms
和Xmx
值后,我的应用现在可以正常运行,而无需重新启动。 在设置Xmx
和Xms
值之前,我还尝试将服务器中的内存增加到7 Xms
,但这也无济于事。 我想知道的是,当有足够的内存可用于应用程序时,系统如何进行OOM。
如果应用程序的内存需求增加,默认堆大小是否会自行扩展? 如果内存已满,为什么没有触发GC?
如果应用程序的内存需求增加,默认堆大小是否会自行扩展?
是的,但最多不超过-Xmx
的值(或JVM选择的该值的默认值)。
如果内存已满,为什么没有触发GC?
GC已触发,但无法收集任何垃圾。 您堆中的所有东西都是垃圾。
“当应用程序有足够的可用内存时,系统如何进行OOM。”
这里有两个可能的问题:
您没有为应用程序的内存需求配置足够的内存,因此可以共享配置的值吗?
应用程序引起内存泄漏问题,因此请记住这一点
资料来源: http : //blog.sysco.no/memory/leak/memory-leak/
Java的主要优点之一是使用垃圾收集器,该垃圾收集器使程序员可以不必进行内存管理。 诸如C ++之类的语言并不是这种情况,因为自代码以来,您必须分配和释放内存。 在一家大公司的经验中,我多次看到内存泄漏问题,导致许多应用程序不可用或性能下降。
另外,内存泄漏属于一类情况,称为软件老化问题。 由于小问题的逐渐累积,软件老化定义了一段时间内的性能损失。 这类问题中的另一个术语是复兴过程。 例如,在一段时间后必须重新启动系统以释放Java虚拟机(JVM)进程累积的内存时,才会发生复兴(COTRONEO,D等,2015)。
基本上,JVM上的垃圾收集器使用一种机制来重用对象空间,该对象空间没有来自根集的任何引用,因此当源代码或配置中出现问题时,一点一点地保持对对象的永久引用。应用程序将填充堆直到达到其极限。
例如,在下图中,将仅收集图内的不可访问对象,所有可访问对象(即使是由错误或错误配置生成的对象)也将保留在堆中
来源http://blog.sysco.no/files/guides/JVMGarbageCollectionV1.1.pdf
“如果应用程序的内存需求增加,默认堆大小是否会自行扩展?”
答案不是,当您的应用程序充满了整个新一代时,JVM将执行次要的GC从新一代对象中释放对象,并且将幸存的对象移入幸存者空间一段时间,直到它们达到一定年龄。 当它们(幸存者空间中的对象)足够成熟并且仍然活着时,这些对象将被提升为老一代,而当老一代已满时,将执行完整的GC。 因此,似乎您的应用程序在某个时刻保留了引用(内存泄漏),整个堆将充满活动对象,因此JVM无法释放它们,并且在某些情况下没有标记来增加内存像这样。
“如果内存已满,为什么没有触发GC?”
在这种情况下,我有一个问题,您如何知道GC是否被触发? 要调整垃圾回收过程,您必须对此进行测量,以便可以尝试使用这些标志来获取有关GC执行的信息。
-XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps -Xloggc:/home/user666/gc.log
另外,您可以使用这个不错的网站来分析日志文件
同样,您可以使用这些标志
-XX:+ HeapDumpOnOutOfMemoryError -XX:HeapDumpPath = / some / where / your / machine
使用这些标志,您将产生一个堆转储,可以使用Memory Analyzer Tool(MAT: https : //www.eclipse.org/mat/downloads.php )对其进行分析,以确定应用程序是否存在内存泄漏。 。
默认的最大堆大小是主内存的1/4。 这假定机器不专用于这一过程。 如果是,则可能要增加最大堆大小。
注意:堆大小仅是堆大小,这只是JVM使用的一个内存区域。 这不是总的内存消耗。 您的JVM需要多少额外的内存取决于它在做什么。
初始大小可以增长到最大大小。 最大大小不会增加,而是您希望进程死掉而不使用更多的堆大小。
如果没有更多信息,我将在4 GB的计算机上尝试运行3 GB的堆(如果它已全部运行),然后查看运行情况。 您可以在top
监视该进程尝试使用多少虚拟内存。
注意:并非所有OutOfMemoryError都相同,因此您需要阅读错误消息以确定问题的真正原因是什么。 例如,您可能用完了线程,perm gen / metaspace或其他一些低级内存问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.