Java:非堆内存分析
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39329455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: non-heap-memory analyzes
提问by stefa ng
we have the problem that our non-heap-memory is growing all the time. so we have to restart our jee (java8) - webapp every 3rd day (as you can see in the screenshot here: screenshot from non-heap- and heap-memory)
我们的问题是我们的非堆内存一直在增长。所以我们必须每 3 天重新启动我们的 jee (java8) - webapp(如您在此处的屏幕截图中所见:来自非堆内存和堆内存的屏幕截图)
I have already tried to find out what fills up that non-heap. But I couldn't find any tool to create a nonheap-dump. do you have any idea how i could investigate on that to find out what elements are increasingly growing?
我已经尝试找出是什么填满了那个非堆。但是我找不到任何工具来创建非堆转储。您知道我如何对此进行调查以找出哪些元素在不断增长吗?
java-version
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-version
tomcat 版本
Apache Tomcat Version 7.0.59
回答by apangin
Non-heap memory usage, as provided by MemoryPoolMXBeancounts the following memory pools:
MemoryPoolMXBean提供的非堆内存使用量计算以下内存池:
- Metaspace
- Compressed Class Space
- Code Cache
- 元空间
- 压缩类空间
- 代码缓存
In other words, standard non-heap memory statistics includes spaces occupied by compiled methods and loaded classes. Most likely, the increasing non-heap memory usage indicates a class loader leak.
换句话说,标准的非堆内存统计包括编译方法和加载类占用的空间。最有可能的是,增加的非堆内存使用量表明类加载器泄漏。
Use
利用
jmap -clstats PID
to dump class loader statistics;jcmd PID GC.class_stats
to print the detailed information about memory usage of each loaded class. The latter requires-XX:+UnlockDiagnosticVMOptions
.
jmap -clstats PID
转储类加载器统计信息;jcmd PID GC.class_stats
打印每个加载类的内存使用情况的详细信息。后者需要-XX:+UnlockDiagnosticVMOptions
.
回答by Peter Lawrey
As @apangin points out it looks like you are using more Metaspace over time. This is usually means you are loading more classes. I would record which classes are being loaded and methods being compiled and try to limit how much this is being done in production on a continuous basis. It is possible you have a library which is generating code continuously but not cleaning it up. This is where looking at what classes are being created could give you a hint as to which one.
正如@apangin 指出的那样,随着时间的推移,您似乎正在使用更多的 Metaspace。这通常意味着您正在加载更多类。我会记录正在加载的类和正在编译的方法,并尝试限制在生产中连续完成的工作量。您可能有一个不断生成代码但没有清理代码的库。在这里查看正在创建的类可以为您提供关于哪个类的提示。
For native non-heap memory.
对于本机非堆内存。
You can look at the memory mapping on Linux with /proc/{pid}/maps
This will let you know how much virtual memory is being used.
您可以查看 Linux 上的内存映射,/proc/{pid}/maps
这将让您知道正在使用多少虚拟内存。
You need to determine whether this is due to
您需要确定这是否是由于
- increasing numbers of threads, or sockets
- direct ByteBuffers being used.
- a third party library which is using native / direct memory.
- 增加线程或套接字的数量
- 直接使用 ByteBuffers。
- 使用本机/直接内存的第三方库。
From looking at your graphs you could reduce your heap and increase your maximum direct memory and extend the restart time to a week or more, but a better solution would be solve the cause.
通过查看您的图表,您可以减少堆并增加最大直接内存并将重启时间延长至一周或更长时间,但更好的解决方案是解决原因。
回答by Codo
With Java 8, class meta data is now in a non-heap memory section called Metaspace(and not in PermGen anymore). If your non-heap memory is mainly consumed by Metaspace, you can figure it out with jstat.
在 Java 8 中,类元数据现在位于称为Metaspace的非堆内存部分(不再位于 PermGen 中)。如果你的非堆内存主要被Metaspace消耗,你可以用jstat弄清楚。
It's not a general tool for analyzing non-heap memory. But it might still help in your case.
它不是分析非堆内存的通用工具。但它可能仍然对您的情况有所帮助。