当前位置: 首页 > 图灵资讯 > 技术篇> 生产环境 OOM 与 GC 问题的处理思路

生产环境 OOM 与 GC 问题的处理思路

来源:图灵教育
时间:2023-05-31 09:11:19

有一定 Java 工作经验的朋友不可避免地会遇到或处理 OOM 和 GC 问题。OOM 和 GC 问题也是面试时面试官经常问的问题。分享多年积累的一些小经验,共同进步。

0x01:未雨绸缪

无论是部署到生产环境中的应用, C/S 结构,还是 B/S 结构应用服务。必须基于 Shell 脚本编写的启动脚本。C/S 结构应用服务 Shell 脚本一般由公司内部开发人员编写;以下一个 C/S 简单启动脚本的结构应用服务。

java  -Xms1024m -Xmx1024m -XX:PermSize=256m                      \-XX:MaxPermSize=512m -XX:-HeapDumpOnOutOfMemoryError             \-XX:HeapDumpPath=./ -XX:+PrintGCDetails -Xloggc:./gc.log  -jar   \plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar -clean -refresh &

而 B/S 应用服务器的启动通常是结构 Shell 脚本。例如,应用服务器 Apache Tomcat bin 目录下的 startup.sh。

生产环境 OOM 与 GC 问题的处理思路_ci

而 Apache Tomcat 的启动 Shell 脚本没有配置 OOM 时,打印 JVM JVM参数和内存快照的打印 GC 日志的JVM参数。因此,生成环境 Tomcat 一般需要提供服务 JVM 参数优化。

如何在线 OOM 和 GC 未雨绸缪?也就是说,我认为我部署的任何服务都会发生 OOM 和 GC 问题。在启动脚本中添加相应的参数,以防止真正发生 OOM 和 GC 问题时,无证可查。

打印 OOM 快照配置:

  • -XX:-HeapDumpOnOutOfMemoryError :当堆内存空间溢出时,输出堆内存快照
  • -XX:HeapDumpPath :指定输入目录

也就是说,当它发生时 OutOfMemoryError 只有在错误的时候才能触发 -XX:HeapDumpOnOutOfMemoryError 输出到 -XX:HeapDumpPath 指定目录。

打印 GC 日志:

  • -XX:+PrintGCDetails:打印 GC 详细的日志信息
  • -Xloggc:GC 输入日志的目录

生产环境 OOM 与 GC 问题的处理思路_JVM_02

0x02:线上分析

有时候不一定要停机才能分析 OOM 和 GC 问题。目前,大型系统服务都配备了监控系统,一旦发现服务运行不健康,就会引发预警。将邮件、短信等发送给运维人员,此时就可以对触发预警的服务进行分析。此时,分析这些提供生成服务的应用服务需要特别小心,造成更严重的生产事故,给公司带来严重损失,但也给自己的评估带来不利影响。

一般用于向上分析 JDK 提供各种操作和维护工具,找出问题所在。

  • 监视工具:jps、jstat、jstatd、jmc
  • 故障排除工具:jcmd、jinfo、jhat、jmap、jsadebugd、jstack

官网:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/

jps (JavaVirtual Machine Process Status Tool): 虚拟机工艺状态工具

命令格式:jps [options] [hostid]

-q : 只生成本地JVM标识符列表,以抑制类名的输出、JAR文件名和传递给main方法的参数。

-m: 显示传递给main方法的参数。输出可能是null嵌入式JVM。

-l : JAR文件的完整路径名显示应用程序main类的完整包名或应用程序的完整路径名。

-v : 显示传输给JVM的参数。

-V : 只生成本地JVM标识符的列表,以抑制类名的输出、JAR文件名和传递给main方法的参数。

-Joption : 将option传递给JVM,其中选项是optionsJava应用程序启动器参考页面中描述的选项之一。

例如,-J-Xms48m将启动内存设置为48 MB。

  • jstat (Java Virtual Machine (JVM) statistics):监控Java虚拟机(JVM)统计信息

命令格式:jstat [ option vmid [interval[s|ms] [count] ]

Interval: 间隔时间 count:次数

class:显示加载器行为的统计信息。

compiler:Java显示 HotSpot VM即时编译器行为的统计信息。

gc:显示垃圾回收堆行为的统计信息。

gccapacity:统计数据显示了世代及其相应的空间容量。

gccause:显示垃圾回收统计信息(相同)-gcutil)摘要包括垃圾收集事件的最终原因和当前(适用时)。

gcnew:显示新一代行为的统计信息。

gcnewcapacity:显示新一代及其相应空间大小的统计信息。

gcold:统计信息显示旧版本和Metaspace统计信息。

gcoldcapacity:显示旧一代大小的统计信息。

gcmetacapacity:显示元空间大小的统计信息。

gcutil:摘要显示垃圾收集统计信息。

printcompilation:Java显示 HotSpot VM编译方法统计信息。

  • jinfo (Configuration Info for Java):生成配置信息

命令格式:jinfo [ option ] pid

-flag 名称 : 打印指定命令行标志的名称和值。

-flag [+ | - ]名称 : 启用或禁用指定的布尔命令行标志。

-flag name = value : 将指定的命令行标志设置为指定的值。

-flags : 将命令行标志打印到JVM。

-sysprops : 以打印Java系统属性为名。

  • jmap (Memory Map for Java):内存映射工具 [ 生成堆转储快照 ]

命令格式:jinfo [ option ] vmid

-dump:[live,] format = b,file = filename :Java堆filename以hprof二进制格式转储。live子选项说明dump是否存活。

-finalizerinfo : 打印正在等待最终确定对象的信息(linux)。

-heap :显示java堆的详细信息,如使用哪种回收器、参数配置、分代等(linux)。

-histo [:live] : 显示堆中对象的统计信息,包括类别、实例数量和总容量。

-clstats : 打印Java堆类加载器的智能统计数据。对于每个类加载器,其名称、活动程度、地址、父加载器及其类别的数量和大小。

-F : -dump或 -当histo选项不响应时,该选项强制生成dump快照(不支持live)。

  • jhat (JVM Heap Analysis Tool):虚拟机堆储快照分析工具

命令格式:jhat [ options ] 堆转储文件

  • jstack (Stack Trace for Java):Java堆栈跟踪工具

命令格式:jstack [ options ] pid

-F : jstack[ -l] 当pid不响应时,强制堆栈转储。

-l : 打印其他关于锁的信息,例如,java.util.concurrent 同步器列表。

-m : 打印混合堆栈跟踪模式,包括 Java 和本机 C/C ++ 框架。

在众多的监测工具和故障排除工具中,常用的是 jps、jstat、jstack 和 jmap

0x03:线下分析

如果肉眼看不到一些问题的端倪,就不能通过未雨绸缪和线上分析来影响生产。这两个步骤需要收集。 JVM 内存快照,线下分析。JDK 以及一些第三方工具,提供了一个非常有用的可视化工具来分析JVM 内存快照。主要有 JDK 提供的 jconsole、VisualVM;Eclipsee由第三方提供 Memory Analyzer(免费)、JProfiler(商业)。常用的化学工具可以参考本文 [ Java内存泄漏 GC 常用易用的工具有哪些? ]