乐趣区

关于jvm调优:生产环境-OOM-与-GC-问题的处理思路

有肯定 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。

而 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 日志输出的目录

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 : 克制类名的输入,JAR 文件名和传递给 main 办法的参数,仅生成本地 JVM 标识符列表。

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

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

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

-V : 克制类名的输入,JAR 文件名和传递给 main 办法的参数,仅生成本地 JVM 标识符的列表。

-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:以 hprof 二进制格局转储 Java 堆 filename。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;第三方提供的有 Eclipse Memory Analyzer(收费)、JProfiler(商业)。罕用能够化工具能够参考该文章 [Java 进行内存泄露 GC 剖析都有哪些罕用好用的工具]

退出移动版