1

我有一个 Grails/Spring 应用程序,它在 Tomcat 等 Web 服务器上的 servlet 容器中运行。有时我的应用程序崩溃,因为 JVM 达到其最大允许内存 (Xmx)。

接下来的错误是“java.lang.OutOfMemoryError”,因为 Java 堆空间已满。

为了防止出现此错误,我想从我的应用程序中检查正在使用的内存量以及当前 JVM 剩余的内存量。

如何从我的应用程序中访问这些参数?

4

4 回答 4

1

您可以尝试Grails Melody 插件,该插件显示 url 中/monitoring相对于您的上下文的信息。

于 2013-08-20T23:27:45.247 回答
1

尝试了解何时引发 OOM,而不是尝试通过应用程序对其进行操作。而且,即使您能够从应用程序中捕获这些值 - 您将如何防止错误?通过显式调用 GC。我知道,

Java 机器规范说 OutOfMemoryError:Java 虚拟机实现已用完虚拟或物理内存,并且自动存储管理器无法回收足够的内存来满足对象创建请求。

因此,GC 保证在抛出 OOM 之前运行。您的应用程序在运行完整的垃圾收集后抛出 OOME,并发现它仍然没有足够的可用堆来继续。

这将是内存泄漏,或者通常您的应用程序可能对内存有很高的要求。大多数情况下,如果在启动应用程序的短时间内抛出 OOM - 通常是应用程序需要更多内存,如果您的服务器运行良好一段时间然后抛出 OOM,那么很可能是内存泄漏。

要发现内存泄漏,请使用上面提到的工具。我使用 new-relic 来监控我的应用程序并检查 GC 运行的频率。

PS Scavenge aka minor-GC aka 并行对象收集器仅用于年轻代,而 PS MarkAndSweep aka major GC aka 并行标记和清除收集器用于老年代。当两者都运行时——它被认为是一个完整的 GC。Minor gc 运行非常频繁——Full GC 的频率相对较低。注意不同堆空间的消耗以分析您的应用程序。

您也可以尝试以下选项 -

如果您经常遇到 OOM,则使用正确的选项启动 java,获取堆转储并使用 jhat 或 eclipse 中的内存分析器进行分析(http://www.eclipse.org/mat/

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=转储文件的路径

于 2013-08-21T22:14:37.247 回答
0

为了防止出现此错误,我想从我的应用程序中检查正在使用的内存量以及当前 JVM 剩余的内存量。

我认为以这种方式进行并不是最好的主意。更好的是调查实际破坏您的应用程序并消除错误或在那里进行一些限制。可能有许多不同的场景,您的应用程序可能会变得不可预测。总而言之 - 为监控目的捕获内存级别是可以的(但有很多专用工具),但在我看来,不建议在应用程序逻辑中依赖这些值,并且是不好的做法

于 2013-08-20T23:48:58.363 回答
0

为此,您将使用分析器来分析您的应用程序和 JVM,而不是使用代码来监控应用程序内部的此类指标。

剖析是动态程序分析的一种形式,例如测量程序的空间(内存)或时间复杂度、特定指令的使用或函数调用的频率和持续时间

以下是一些不错的 java 分析器:

http://visualvm.java.net/(免费)

http://www.ej-technologies.com/products/jprofiler/overview.html(付费)

于 2013-08-21T00:01:50.210 回答