Java:非堆内存分析

2022-09-02 04:46:41

我们有一个问题,我们的非堆内存一直在增长。因此,我们必须每3天重新启动我们的jee(java8) - webapp(正如您在此处的屏幕截图中看到的那样:来自非堆和堆内存的屏幕截图)

我已经试图找出是什么填满了这个非堆。但是我找不到任何工具来创建非heap dump。你知道我该如何调查以找出哪些元素正在日益增长吗?

java-version

java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

猫咪版

Apache Tomcat Version 7.0.59

答案 1

由 MemoryPoolMXBean 提供的非堆内存使用率对以下内存池进行计数:

  • 元空间
  • 压缩类空间
  • 代码缓存

换句话说,标准非堆内存统计信息包括已编译方法和装入类占用的空间。最有可能的是,非堆内存使用量的增加表明类装入器泄漏。

  • jmap -clstats PID转储类装入器统计信息;
  • jcmd PID GC.class_stats以打印有关每个已装入类的内存使用情况的详细信息。后者需要 .-XX:+UnlockDiagnosticVMOptions

答案 2

正如@apangin所指出的那样,随着时间的推移,看起来你正在使用更多的元空间。这通常意味着您正在加载更多的类。我会记录正在加载的类和正在编译的方法,并尝试限制在生产中连续完成的工作量。您可能有一个库,它不断生成代码,但不清理它。在这里,查看正在创建的类可以为您提供有关哪一个类的提示。


对于本机非堆内存。

您可以查看Linux上的内存映射,这将让您知道正在使用多少虚拟内存。/proc/{pid}/maps

您需要确定这是否是由于

  • 增加线程数或套接字数
  • 正在使用的直接字节缓冲器。
  • 使用本机/直接内存的第三方库。

通过查看图形,您可以减少堆并增加最大直接内存,并将重新启动时间延长到一周或更长时间,但更好的解决方案是解决问题。


推荐