RedHat Enterprise Linux 6上的进程超出线程堆栈大小限制?

我在RHEL 6.3上运行了几个进程,但由于某些原因,它们超出了线程堆栈大小。

例如,Java进程在启动时在运行时被赋予了-Xss256k的堆栈大小,并且在实际代码中使用pthread_attr_setstacksize()给C ++进程提供了1MB的线程堆栈大小。

但是,由于某些原因,这些过程并没有遵循这些限制,我不知道为什么。

例如,当我跑步

pmap -x <pid> 

对于C ++和Java进程,我可以看到每个线程有数百个“anon”线程(我已经确认这些线程是由这些进程中的每一个创建的内部工作线程),但是这些线程的分配值都是64MB,而不是设置的限制以上:

00007fa4fc000000 168 40 40 rw--- [ anon ] 
00007fa4fc02a000 65368 0 0 ----- [ anon ] 
00007fa500000000 168 40 40 rw--- [ anon ] 
00007fa50002a000 65368 0 0 ----- [ anon ] 
00007fa504000000 168 40 40 rw--- [ anon ] 
00007fa50402a000 65368 0 0 ----- [ anon ] 
00007fa508000000 168 40 40 rw--- [ anon ] 
00007fa50802a000 65368 0 0 ----- [ anon ] 
00007fa50c000000 168 40 40 rw--- [ anon ] 
00007fa50c02a000 65368 0 0 ----- [ anon ] 
00007fa510000000 168 40 40 rw--- [ anon ] 
00007fa51002a000 65368 0 0 ----- [ anon ] 
00007fa514000000 168 40 40 rw--- [ anon ] 
00007fa51402a000 65368 0 0 ----- [ anon ] 
00007fa518000000 168 40 40 rw--- [ anon ] 
...

但是,当我在上述过程中使用所有64MB'匿名'线程运行以下代码时

cat /proc/<pid>/limits | grep stack 

Max stack size 1048576 1048576 bytes 

它显示了1MB的最大线程堆栈大小,所以对于这里发生的事情有点困惑。 另外,调用这些程序的脚本也会设置'ulimit -s 1024'。

应该指出的是,这似乎只发生在使用非常高端的机器(例如48GB RAM,24个CPU核心)时。 这个问题不会出现在功能不太强大的机器上(例如4GB RAM,2个CPU核心)。

任何帮助了解这里发生的事情将不胜感激。


原来,RHEL6 2.11已经改变了线程模型,使得每个线程在可能的情况下都被分配了自己的线程池,所以在一个更大的系统上,你可能会看到它占用了64MB。 在64位上,允许的最大线程池数量更多。

解决这个问题的方法是添加

export LD_PRELOAD=/path/to/libtcmalloc.so 

在启动进程的脚本中(而不是使用glibc2.11)

关于此的更多信息可从以下网址获得:

Linux glibc> = 2.10(RHEL 6)malloc可能会显示过多的虚拟内存使用情况https://www.ibm.com/developerworks/mydeveloperworks/blogs/kevgrig/entry/linux_glibc_2_10_rhel_6_malloc_may_show_excessive_virtual_memory_usage?lang=en

glibc bug malloc为多线程应用程序使用过多的内存http://sourceware.org/bugzilla/show_bug.cgi?id=11261

Apache hadoop通过设置MALLOC_ARENA_MAX解决了这个问题https://issues.apache.org/jira/browse/HADOOP-7154


使用/proc/1234/limits报告的堆栈大小通过setrlimit(2)(可能由PAM子系统在登录时)设置。

我没有真正的想法,为什么实际的堆栈段似乎是64Mb每个。 也许你的大服务器使用巨大的页面(但你的桌面不)。

例如,在调用你的程序的脚本中,你可能会调用setrlimit (也许用ulimit bash内建函数,或者limit zsh内建函数)。


您可以使用ulimit -s <size_in_KB>设置进程的最大堆栈大小。 您也可以使用ulimit -s来查看当前的限制。

链接地址: http://www.djcxy.com/p/80283.html

上一篇: Processes exceeding thread stack size limit on RedHat Enterprise Linux 6?

下一篇: virtual memory concepts