2012-11-01 38 views
4

我有幾個進程在RHEL 6.3上運行,但由於某些原因,它們超出了線程堆棧大小。在RedHat Enterprise Linux 6上超過線程堆棧大小限制的進程?

例如,Java進程在運行時在啓動時被賦予了-Xss256k的堆棧大小,並且C++進程在實際代碼中使用pthread_attr_setstacksize()給出了1MB的線程堆棧大小。

出於某種原因然而,這些過程都沒有堅持到這些限制,我不知道爲什麼。

例如,當我運行

pmap -x <pid> 

爲C++和Java過程中,我可以看到每個數百「不久又看到」的線程(我已經證實是由每個這些創建的內部工作線程過程),但這些都各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核心)。

任何幫助瞭解這裏發生的事情將不勝感激。

回答

6

原來,RHEL6 2.11已更改的線程模型,以便在可能被分配自己的線程池,這樣一個大的系統上可能會看到它抓住高達64MB的每個線程。在64位上,允許的最大線程池數量更多。

此此修復程序是在啓動過程(而不是使用glibc2.11)腳本添加

export LD_PRELOAD=/path/to/libtcmalloc.so 

一些這方面的更多inforation是可從以下

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的錯誤的malloc使用過多存儲器,用於多線程應用 http://sourceware.org/bugzilla/show_bug.cgi?id=11261

阿帕奇的hadoop已經通過設置MALLOC_ARENA_MAX https://issues.apache.org/jira/browse/HADOOP-7154

+0

感謝這個答案,爲我節省了很多時間! 爲什麼進行此更改併發布時沒有任何提醒? – omid

0

/proc/1234/limits報告的堆棧大小設置爲setrlimit(2)(可能在登錄時通過PAM子系統)。

我沒有真正的想法,爲什麼實際的堆棧段似乎每個64MB。也許你的大服務器使用huge pages(但你的桌面不)。例如

您可能會打電話setrlimit(可能與ulimit bash內建值或limit zsh內建值)。腳本調用你的程序。

+0

謝謝巴西爾 - 我按照你說的去做 - 在調用程序的腳本中設置ulimit -s 1024,但仍然是相同的結果。 – Rory

0

可以使用ulimit -s <size_in_KB>設置最大堆棧大小進程。您也可以使用ulimit -s來查看當前的限制。

+0

感謝Spap,我已經在啓動這些進程的腳本中這麼做了 - 它似乎沒有影響任何內容,對於沒有提及的道歉,我已經更新了上面的帖子以反映這一點。 – Rory

0

固定的問題@rory對於你的回答,64MB塊地址應該是堆地址,但現在地址就像是堆棧地址00007fa50c02a000,對吧?