随着堆利用率接近 100% 并且不可避免的 OutOfMemoryError 可能导致生产 JVM 崩溃,倾向于实时 JAVA 应用程序的 DevOps 专业人员不会要求一种机制来强制 Java 垃圾收集并释放几兆字节的内存。
不幸的是,这种立即释放内存的愿望肯定是徒劳的,因为在 Java 中没有办法强制进行垃圾收集 (GC)。但是,这里有五种策略可以让 Java 虚拟机 ( JVM ) 确定任务的优先级。
开发人员可以在其代码中的任何位置调用 System.gc() 来指示 JVM 优先考虑垃圾收集。当开发人员调用此方法时——JVM 上没有极端负载——Java GC 循环将在几秒钟内发生。
System.gc();
另一种选择是使用Runtime.getRuntime().gc()调用。这是JDK为想要强制进行 Java 垃圾收集的开发人员提供的第二个功能。Runtime.getRuntime().gc()调用实际上只是在后台调用方法System.gc ( ) 。结果,这两个方法调用是完全一样的。
Runtime.getRuntime().gc();
Java 内存映射 (JMAP) 实用程序有一个打印 Java 堆直方图的方法。jmap命令的一个副作用是,当它被调用时,它会强制执行垃圾收集例程。但是,这并不是强制进行 Java 垃圾收集的万无一失的方法。如果 JVM 很忙并且无法执行 GC 循环,则该命令将出错。
$ jmap -histo:live 7544
Figure 1 您可以尝试使用 JDK 的 JMAP 和 JCMD 实用程序强制执行 Java 垃圾收集。
Java 诊断命令 (JCMD) 是另一个JDK 实用程序,如果 JVM 可以安全地安排 stop-the-world 暂停,它将触发垃圾收集例程。如果不是,此命令将以与jmap实用程序相同的方式出错。
$ jcmd 7544 GC.run
JConsole 和 Java Mission Control 都提供了与 Java 诊断命令实用程序交互的用户友好界面,可用于强制执行 Java 垃圾收集。JConsole监控工具在其内存管理页面上提供了一个按钮,上面写着Run Garbage Collection。Java Mission Control 允许开发人员选择任何jcmd 开关——包括GC.run——并通过单击按钮执行命令。
但是,这些工具在 Java 垃圾收集方面并没有做任何独特的事情。他们只是在幕后调用jcmd实用程序。
Figure 2 Java Mission Control 和 JConsole 都有可视化工具,允许您强制执行 Java GC。
虽然开发人员永远不能真正强制 Java 垃圾收集,但有一些方法可以让 JVM 优先考虑内存管理功能。回顾一下,尝试强制执行 Java 垃圾收集的五种方法是: