Jboss(Java)进程的驻留内存使用量逐渐增加
Posted
技术标签:
【中文标题】Jboss(Java)进程的驻留内存使用量逐渐增加【英文标题】:Gradual increase in Resident Memory usage by Jboss(Java) process 【发布时间】:2015-02-10 21:29:17 【问题描述】:我们面临的问题是 Java 进程的驻留内存逐渐增长。我们将 Xmx 定义为 4096 MB 和 XX:MaxPermSize=1536m。活动线程的数量 ~1500,定义的 Xss 为 256K。
应用服务器(JBoss 6.1)启动时使用的常驻内存为~5.6GB(一直使用top命令监控);它逐渐增长(每天大约 0.3 到 0.5 Gb)直到增长到 ~7.4 Gb,当内核的 OOM 杀手由于 RAM 空间不足而终止进程时(服务器有 9GB 的 RAM)。
我们一直在定期监视线程转储 - 没有线程泄漏的嫌疑。我们仍然无法弄清楚这些额外的内存是从哪里来的。
Pmap 输出显示了许多 Anon 块(除了用于堆栈和堆的常规块),主要位于 64 Mb 的竞技场中,这些块在堆、perm gen 和堆栈的内存使用方面未计入。
在堆转储中,我们也尝试过寻找 DirectByteBuffers 和 sun.misc.Unsafe 对象,它们通常用于非堆内存分配,但对象的数量以及内存容量似乎是名义上的。即使在这些对象被 GC 之后,是否仍有未释放的本机内存?任何其他可能导致用尽非堆内存的类?
我们的应用程序确实有自己的本机调用,但某些第三方库可能有它们。
关于可能导致此问题的任何想法?还有什么其他细节/工具可以进一步帮助调试这种增加吗?任何我们应该注意的已知问题?平台:在 Centos 5.6 上运行的 Jboss 6.1。
【问题讨论】:
假设您已阅读 Oracle 的内存泄漏故障排除指南oracle.com/technetwork/java/javase/tools-141261.html 本题相关:***.com/questions/26041117/… 【参考方案1】:RSS 使用量的增加可能是由本机内存泄漏引起的。
一个常见的问题是由于未关闭 ZipInputStream
/GZIPInputStream
而导致本机内存泄漏。
打开ZipInputStream
的典型方式是调用Class.getResource
/ClassLoader.getResource
并在java.net.URL
实例上调用openConnection().getInputStream()
,或者调用Class.getResourceAsStream
/ClassLoader.getResourceAsStream
。必须确保这些流始终关闭。
您可以使用jemalloc 来调试本机内存泄漏,方法是通过指定MALLOC_CONF
环境变量中的设置来启用malloc 采样分析。此博客文章中提供了详细说明:http://www.evanjones.ca/java-native-leak-bug.html。 This blog post 也有关于使用 jemalloc 调试 java 应用程序中的本机内存泄漏的信息。
同一博客还包含有关另一个 native memory leak related to ByteBuffers 的信息。
【讨论】:
查看这个答案:***.com/a/35610063,它有更多关于 Java 原生内存泄漏的细节。【参考方案2】:Java 和 glibc >= 2.10(包括 Ubuntu >= 10.04,RHEL >= 6)存在一个已知问题。
解决方法是设置这个环境。多变的:
export MALLOC_ARENA_MAX=4
有一篇关于设置 MALLOC_ARENA_MAX 的 IBM 文章 https://www.ibm.com/developerworks/community/blogs/kevgrig/entry/linux_glibc_2_10_rhel_6_malloc_may_show_excessive_virtual_memory_usage?lang=en
This blog post says
已知常驻内存会以类似于 内存泄漏或内存碎片。
在 Google 或 SO 上搜索 MALLOC_ARENA_MAX 以获取更多参考。
您可能还想调整其他 malloc 选项以优化分配内存的低碎片:
# tune glibc memory allocation, optimize for low fragmentation
# limit the number of arenas
export MALLOC_ARENA_MAX=2
# disable dynamic mmap threshold, see M_MMAP_THRESHOLD in "man mallopt"
export MALLOC_MMAP_THRESHOLD_=131072
export MALLOC_TRIM_THRESHOLD_=131072
export MALLOC_TOP_PAD_=131072
export MALLOC_MMAP_MAX_=65536
【讨论】:
以上是关于Jboss(Java)进程的驻留内存使用量逐渐增加的主要内容,如果未能解决你的问题,请参考以下文章