Java JVM“;“奇怪”;行为

Java JVM“;“奇怪”;行为,java,out-of-memory,alfresco,Java,Out Of Memory,Alfresco,我在Java8上运行Alfresco实例时遇到了一个“奇怪”的行为。 有时,应用程序会使用所有可用的RAM并导致OOM异常。 我们制作了一个HeapDump来查看发生了什么,并且转储的过程与所用内存的主要部分相关。 知道那里发生了什么吗 每次执行转储时,内存都会被释放,并在之后立即上升。 我无法理解这种行为背后的逻辑 无论何时尝试从visualvm获取堆转储,它首先: 触发完全垃圾收集以清除“死”对象。可以通过在垃圾收集日志中搜索“完整GC(堆转储启动的GC)”来找到这些事件 将剩余的“活动

我在Java8上运行Alfresco实例时遇到了一个“奇怪”的行为。 有时,应用程序会使用所有可用的RAM并导致OOM异常。 我们制作了一个HeapDump来查看发生了什么,并且转储的过程与所用内存的主要部分相关。 知道那里发生了什么吗

每次执行转储时,内存都会被释放,并在之后立即上升。 我无法理解这种行为背后的逻辑

无论何时尝试从visualvm获取堆转储,它首先:

  • 触发完全垃圾收集以清除“死”对象。可以通过在垃圾收集日志中搜索“完整GC(堆转储启动的GC)”来找到这些事件
  • 将剩余的“活动”对象转储到文件中
这就是原因,无论何时进行堆转储,实际的堆利用率都会下降。这也表明,在进行堆转储的环境中,您可能没有内存泄漏或其他问题,这些问题通常会导致OutOfMemory

我建议使用以下JVM参数,这些参数非常有助于排除OutOfMemory错误:

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=C:\path_where_heap_dumps_will_be_generated
-XX:OnOutOfMemoryError=do_something_to_recover_from_it

请查看详细信息。

无论何时尝试从visualvm获取堆转储,它首先:

  • 触发完全垃圾收集以清除“死”对象。可以通过在垃圾收集日志中搜索“完整GC(堆转储启动的GC)”来找到这些事件
  • 将剩余的“活动”对象转储到文件中
这就是原因,无论何时进行堆转储,实际的堆利用率都会下降。这也表明,在进行堆转储的环境中,您可能没有内存泄漏或其他问题,这些问题通常会导致OutOfMemory

我建议使用以下JVM参数,这些参数非常有助于排除OutOfMemory错误:

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=C:\path_where_heap_dumps_will_be_generated
-XX:OnOutOfMemoryError=do_something_to_recover_from_it

请查看详细信息。

似乎与此线程相关:。我们应该强制GC还是从另一个方向看呢?你确定你的应用程序不会使用这样的内存吗?您可能会上传非常大的文件,或者根据某些条件创建数千/数百万个重类,等等?应用程序可能会使用大量内存,但为什么每次我们转储堆时,所有内存都会被释放?据我所知,GC释放了未引用的内存,这意味着应用程序不需要更多的内存。接下来是我的初始问题,每次我们转储时,内存都会下降,然后又开始上升。这是什么意思?您是使用java-XX:+HeapDumpOnOutOfMemoryError手动还是自动转储它?让我们看看。似乎与此线程相关:。我们应该强制GC还是从另一个方向看呢?你确定你的应用程序不会使用这样的内存吗?您可能会上传非常大的文件,或者根据某些条件创建数千/数百万个重类,等等?应用程序可能会使用大量内存,但为什么每次我们转储堆时,所有内存都会被释放?据我所知,GC释放了未引用的内存,这意味着应用程序不需要更多的内存。接下来是我的初始问题,每次我们转储时,内存都会下降,然后又开始上升。这是什么意思?你是用java-XX:+HeapDumpOnOutOfMemoryError手动还是自动转储它?让我们来看看。我已经完成了。OOM不再发生。我们已经改变了在露天处理安全问题的方式。情况有所好转,但仍然很尴尬。我已经做到了。OOM不再发生。我们已经改变了在露天处理安全问题的方式。情况有所好转,但在记忆方面仍然很尴尬