Java:非堆内存分析

ste*_* ng 10 java jvm memory-leaks

我们遇到的问题是我们的非堆内存一直在增长.所以我们必须每隔3天重启我们的jee(java8) - webapp(正如你在这里的截图中看到的那样:来自非堆和堆内存的截图)

我已经试图找出填满非堆的东西了.但我找不到任何工具来创建非堆转储.你有什么想法我可以调查一下,找出哪些元素越来越多?

Java的版本

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)
Run Code Online (Sandbox Code Playgroud)

Tomcat的版本

Apache Tomcat Version 7.0.59
Run Code Online (Sandbox Code Playgroud)

apa*_*gin 6

MemoryPoolMXBean提供的非堆内存使用情况会计数以下内存池:

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

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

使用

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


Pet*_*rey 1

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


对于本机非堆内存。

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

您需要确定这是否是由于

  • 增加线程或套接字的数量
  • 直接使用 ByteBuffer。
  • 使用本机/直接内存的第三方库。

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

  • 看起来OP的图表显示了[MemoryPoolMXBean](http://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html)提供的内存使用情况。标准非堆统计数据中不包含线程、套接字、直接字节缓冲区或第三方库内存。非堆池只是代码缓存、元空间和压缩类空间。就是这样。 (3认同)