我们正面临着Java进程的Resident内存逐渐增长的问题。我们将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。
答案 0 :(得分:0)
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
已知驻留记忆以类似于a的方式蠕变 内存泄漏或内存碎片。
在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
答案 1 :(得分:0)
RSS使用量的增加可能是由本机内存泄漏引起的。
一个常见问题是由于未关闭ZipInputStream
/ GZIPInputStream
而导致的本机内存泄漏。
打开ZipInputStream
的典型方式是致电Class.getResource
/ ClassLoader.getResource
并在openConnection().getInputStream()
实例上调用java.net.URL
或致电{ {1}} / Class.getResourceAsStream
。必须确保这些流始终关闭。
您可以使用jemalloc通过指定ClassLoader.getResourceAsStream
环境变量中的设置启用malloc采样分析来调试本机内存泄漏。此博客文章中提供了详细说明:http://www.evanjones.ca/java-native-leak-bug.html。 This blog post还有关于使用jemalloc调试java应用程序中的本机内存泄漏的信息。
同一博客还包含有关其他native memory leak related to ByteBuffers的信息。