Java:非堆内存分析

时间:2016-09-05 11:18:08

标签: java memory-leaks jvm

我们遇到的问题是我们的非堆内存一直在增长。所以我们必须每隔3天重启我们的jee(java8) - webapp(正如你在屏幕截图中看到的那样:screenshot from non-heap- and heap-memory

我已经尝试找出填满非堆的内容。但我找不到任何创建非堆放的工具。你有什么想法我可以调查一下,找出哪些元素在不断增长?

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)

Tomcat的版本

Apache Tomcat Version 7.0.59

3 个答案:

答案 0 :(得分:4)

MemoryPoolMXBean提供的非堆内存使用量计算以下内存池:

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

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

使用

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

答案 1 :(得分:0)

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

对于本机非堆内存。

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

您需要确定这是否是由于

  • 越来越多的线程或套接字
  • 直接使用ByteBuffers。
  • 使用本机/直接内存的第三方库。

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

答案 2 :(得分:0)

使用Java 8,类元数据现在位于名为 Metaspace 的非堆内存部分中(而不再是PermGen中)。如果您的非堆内存主要由 Metaspace 使用,您可以使用jstat找出它。

它不是分析非堆内存的通用工具。但它可能对你的情况有所帮助。