转载

OutOfMemoryError相关JVM参数

JVM

OutOfMemoryError相关JVM参数 JVM提供了很多处理 OutOfMemoryError 有用的参数。在本文中,我们介绍讲解一下这些参数。当你再遇到 OutOfMemoryError 进行故障排查时会很有帮助,这些参数如下:

  1. -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath
  2. -XX:OnOutOfMemoryError
  3. -XX:+ExitOnOutOfMemoryError
  4. -XX:+CrashOnOutOfMemoryError

下面我们来详细的看下每个参数的意义和用法。

1. -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath

Heap Dump 就是内存的一个映像,它包含了内存中存在的对象的详细信息,包括对象包含的实际数据、对象之间的引用关系等等。 Heap Dump 是用来诊断内存相关问题最重要的工具。

为了诊断 OutOfMemoryError 或任何与内存相关的问题,当发生内存溢出或者将要发生内存溢出的时候,我们首先需要去捕获 Heap Dump ,在发生内存溢出的时候很难手动捕获 Heap Dump ,因为我们不知道什么时候会抛出 OutOfMemoryError ,但是,在命令行中启动应用程序时,可以通过传递以下JVM参数来自动执行捕获 Heap Dump 的操作:

-XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath={HEAP-DUMP-FILE-PATH}

例子如下:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/crashes/my-heap-dump.hprof

-XX:HeapDumpPath 指定了内存映像文件的存储路径。

只要给JVM传递了这2个参数,当发生内存溢出的时候,JVM会自动在指定目录下生成内存映像文件。

获取内存映像文件后,就可以使用 HeapHero 和 Eclipse MAT 之类的工具来分析 Heap Dump 了。

2. -XX:OnOutOfMemoryError

当发生内存溢出的时候,还可以让JVM调用任一个shell脚本。大多数时候,内存溢出并不会导致整个应用都 Crash 掉,但是,一旦发生OutOfMemoryError,最好重新启动应用程序。

因为 OutOfMemoryError 可能会使应用程序处于不稳定状态。一个不稳定的应用可能会提供错误的响应。使用举例:

-XX:OnOutOfMemoryError=/scripts/restart-myapp.sh

传递此参数时,每当抛出 OutOfMemoryError 时,JVM就会调用 /scripts/restart-myapp.sh 脚本。在此脚本中,您可以编写代码以优雅地方式重新启动应用程序。

3. -XX:+CrashOnOutOfMemoryError

如果给JVM传递了这个参数时,当发生 OutOfMemoryError 的时候JVM就会退出,同时,JVM会产生文本和二进制格式的崩溃日志(如果启用了核心文件)。但是,就我个人而言不建议配置上这个参数的,我们应该是以一种优雅的方式退出程序,粗暴的退出方式可能会损害正在进行的事务。

以前遇到过有个应用配置了 -XX:+CrashOnOutOfMemoryError 这个参数,当发生内存溢出的时候,JVM立马就退出了,并且在控制台有如下日志打印:

Aborting due to java.lang.OutOfMemoryError: GC overhead limit exceeded
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (debug.cpp:308), pid=26064, tid=0x0000000000004f4c
#  fatal error: OutOfMemory encountered: GC overhead limit exceeded
#
# JRE version: Java(TM) SE Runtime Environment (8.0_181-b13) (build 1.8.0_181-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode windows-amd64 compressed oops)
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:/workspace/tier1app-svn/trunk/buggyapp/hs_err_pid26064.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#

从日志中可以看出来,在 C:/workspace/tier1app-svn/trunk/buggyapp/hs_err_pid26064.log 目录下生成了崩溃日志文件,它里面包含了崩溃的详细信息。可以使用诸如 fastThread 的工具来分析 hs_err_pid 这个日志, 但是 hs_err_pid 中存在的大多数时间信息都是非常基本的,不足以对 OutOfMemoryError 的原因进行定位。

4. -XX:+ExitOnOutOfMemoryError

传递此参数时,抛出 OutOfMemoryError 时,JVM将立即退出。如果您想终止应用程序,则可以传递此参数。但就我个人而言,我不希望配置该参数,因为我们应该始终以实现正常退出为目标。突然退出可能/将危害正在进行的事务。

我使用此 -XX:+ ExitOnOutOfMemoryError JVM参数运行了相同的内存泄漏程序。与 -XX:+ CrashOnOutOfMemoryError 不同,此JVM参数不会生成任何文本/二进制文件,直接就退出了。

英文原文见: blog.gceasy.io

OutOfMemoryError相关JVM参数

本文由nock 创作,采用 知识共享署名4.0 国际许可协议进行许可

本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名

最后编辑时间为: Dec 17, 2019 at 11:56 pm

原文  https://fashengba.com/post/java-OutOfMemoryError.html
正文到此结束
Loading...