查看Java元空间区域


有时您的应用程序可能会遇到本文中讨论“java.lang.OutOfMemoryError: Metaspace”。在这种情况下,您可能希望查看 JVM 的元空间区域中加载的内容是什么。简而言之,JVM 内存中的 Metaspace 区域包含执行应用程序所需的类元数据定义。

如果您能够了解加载到内存中的类是什么,那么它将很好地了解 JVM 内存的 Metaspace 区域中存在哪些内容。在这篇文章中,让我们探索可用于查看加载到元空间中的类的选项。
以下是查看元空间中加载的类的选项:

  1. -verbose:class
  2.  -Xlog:class+load
  3. jcmd GC.class_histogram
  4. 程序化方法
  5. 堆转储分析

1、-verbose:class
如果您在 Java 版本 8 或更低版本上运行,则可以使用此选项。当您在启动期间将“-verbose:class”选项传递给您的应用程序时,它将打印所有加载到内存中的类。加载的类将打印在标准错误流中(即控制台,如果您没有将错误流路由到日志文件)。

java {app_name} -verbose:class

2、-Xlog:class+load
如果您在 Java 版本 9 或更高版本上运行,则可以使用此选项。当您在启动期间将“-Xlog:class+load”选项传递给您的应用程序时,它将打印所有加载到内存中的类。加载的类将打印在您配置的文件路径中。

java {app_name} -Xlog:class+load=info:/opt/log/loadedClasses.txt

 3、jcmd GC.class_histogram
JDK 包含一个名为“jcmd”的工具。您可以在 JVM 运行时调用此工具来检查元空间区域的内容。当您使用“GC.class_histogram”参数调用此工具时,它将打印加载到内存中的类列表。您可以在两种模式下调用此工具:

1、输出在控制台上加载的类

jcmd {pid} GC.class_histogram

当您调用如上所示的“jcmd”时,它将在控制台中打印所有加载的类。这里 {pid} 是您的 java 应用程序的进程 ID。 

2、输出在文件上加载的类

jcmd {pid} GC.class_histogram filename={file-path}

当您如上所示调用“jcmd”时,它将打印“文件名”参数中指定的文件路径中的所有加载类。这里 {pid} 是您的 java 应用程序的进程 ID。

4、程序化方法
您还可以使用编程方法打印加载到内存中的类。开源 Guava 库

ClassPath classPath = ClassPath.from(BuggyAppLoader.class.getClassLoader()); Set<ClassInfo> class = classPath.getAllClasses();

5.、转储分析
查看加载到内存中的类的另一个选项是检查堆转储。堆转储报告加载到内存中的所有数据、对象、类。您可以使用此处给出的一种方法来捕获堆转储。捕获堆转储后,您可以使用Eclipse MATHeapHero等堆转储分析工具