ubuntuusers.de

fork: Cannot allocate memory

Status: Ungelöst | Ubuntu-Version: Ubuntu 9.10 (Karmic Koala)
Antworten |

jucs

Anmeldungsdatum:
15. August 2006

Beiträge: 700

Hallo ihr,

ich habe ein kleines Problem. Und zwar versuche ich, testweise in einem Beispielprogramm ~50.000 Threads zu erzeugen. Unglücklicherweise steigt der Kernel bei irgendwas um 30.000 aus und *kein Prozess* darf mehr neue Threads starten. Die Fehlermeldung auf der Bash deutet darauf hin:

fork: Cannot allocate memory

Mein Arbeitsspeicher ist bei 30.000 Threads noch bei weitem nicht voll; der Kernel scheint also irgendeinen begrenzten Pool für Threads zu haben. Meine Frage ist nun - wie erhöhe ich seine Größe?

Und bitte gebt keine Antworten mit der Frage nach dem Sinn, das ist nicht relevant.

Vielen Dank!

Onli Team-Icon

Ehemalige
Avatar von Onli

Anmeldungsdatum:
1. August 2005

Beiträge: 6941

Stoppt er vielleicht bei 32767? 😉
Schau dir mal cat /proc/sys/kernel/threads-max an. Ein

sudo su
echo 50000 > /proc/sys/kernel/threads-max

sollte helfen.

jucs

(Themenstarter)

Anmeldungsdatum:
15. August 2006

Beiträge: 700

Danke für deinen Hinweis, aber so weit war ich schon - das ist entsprechend hoch:

root@comp002-adk:~# cat /proc/sys/kernel/threads-max
1048576

Zusätzlich habe ich nun noch zwei Werte angepasst, die in Kombination das Problem fast lösten:

echo 1048576 >/proc/sys/kernel/pid_max

und

echo 1 >/proc/sys/vm/overcommit_memory

Mein Testprogramm bekommt nun praktisch sofort 32.755 Threads und kein anderer Prozess meldet irgendwelche Fehler. Starte ich mein Testprogramm mehrfach, bringe ich es einfach auf 100.000 Threads (und mehr habe ich nicht getestet).

Das Problem ist jetzt: Eigentlich sollte die erste Instanz schon 50.000 Threads erschaffen. pthread_create() gibt aber seltsamerweise ab dem 32.756ten Thread nurnoch Error 12 zurück. Irgendeine Idee?

Onli Team-Icon

Ehemalige
Avatar von Onli

Anmeldungsdatum:
1. August 2005

Beiträge: 6941

Es ist nunmal die Frage, was dir da ausgeht. Geht da der virtuelle Speicher aus, bzw bei der Threadverwaltung die Adressierung? Ich weiß es nicht, diese Interna kenne ich nicht genau genug.

jucs

(Themenstarter)

Anmeldungsdatum:
15. August 2006

Beiträge: 700

Onli schrieb:

Es ist nunmal die Frage, was dir da ausgeht. Geht da der virtuelle Speicher aus, bzw bei der Threadverwaltung die Adressierung? Ich weiß es nicht, diese Interna kenne ich nicht genau genug.

Nun, wenn aber mehrere Prozesse jeweils wieder diese Anzahl an Threads bekommen, dann scheint es doch, dass da garnichts ausgeht und es eher irgendein künstliches Limit ist, welches ich bisher vergessen habe abzustellen.

Desweiteren sieht mein Speicher auch recht human aus, hier mit einem Prozess, der 32.755 Threads besitzt:

[jucs@comp002-adk:~]$ ps Haux | grep bridge | wc -l
32756
[jucs@comp002-adk:~]$ cat /proc/meminfo 
MemTotal:        8194672 kB
MemFree:         4722264 kB
Buffers:          408808 kB
Cached:           642420 kB
SwapCached:            0 kB
Active:          1724008 kB
Inactive:         519952 kB
Active(anon):    1199408 kB
Inactive(anon):       16 kB
Active(file):     524600 kB
Inactive(file):   519936 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:               832 kB
Writeback:             0 kB
AnonPages:       1192760 kB
Mapped:           139016 kB
Slab:             622284 kB
SReclaimable:     352980 kB
SUnreclaim:       269304 kB
PageTables:       156184 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     8194672 kB
Committed_AS:   270290424 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      330668 kB
VmallocChunk:   34359392251 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       48640 kB
DirectMap2M:     8339456 kB

Und jetzt das ganze mit 2 Prozessen, die jeweils 32.755 Threads erhalten:

[jucs@comp002-adk:~]$ ps Haux | grep bridge | wc -l
65511
[jucs@comp002-adk:~]$ cat /proc/meminfo 
MemTotal:        8194672 kB
MemFree:         3734112 kB
Buffers:          409172 kB
Cached:           642500 kB
SwapCached:            0 kB
Active:          1993480 kB
Inactive:         520236 kB
Active(anon):    1468728 kB
Inactive(anon):       16 kB
Active(file):     524752 kB
Inactive(file):   520220 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:               684 kB
Writeback:             0 kB
AnonPages:       1462052 kB
Mapped:           139056 kB
Slab:             945648 kB
SReclaimable:     434664 kB
SUnreclaim:       510984 kB
PageTables:       287508 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     8194672 kB
Committed_AS:   538755816 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      330668 kB
VmallocChunk:   34359392251 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       48640 kB
DirectMap2M:     8339456 kB

Das ist doch seltsam? Immer genau diese Anzahl pro Prozess, aber beliebig viele Prozesse gleichzeitig.

Onli Team-Icon

Ehemalige
Avatar von Onli

Anmeldungsdatum:
1. August 2005

Beiträge: 6941

So einfach ist das nicht.

Ein Prozess bekommt nicht einfach Zugriff auf den gesamten Speicher. Jedem Prozess wird ein virtueller Speicherbereich zugeordnet. In diesem Speicherbereich spawnst du deine Threads, die zwar alle auf dem gleichen Speicher arbeiten, aber ja auch selbst Speicher belegen (ob das jetzt ein eigener Stack ist oder sonstwas ist ja erstmal egal). Da liegt bestimmt irgendwo ein Maximum, abhängig von der Eigengröße der Threads und vielleicht auch bei der Adressierung derselben.

Aber ich will nicht gesagt haben, dass man die Anzahl nicht weiter erhöhen kann 😉

jucs

(Themenstarter)

Anmeldungsdatum:
15. August 2006

Beiträge: 700

Nun, soweit mir bekannt ist, darf ein Prozess erstmal praktisch beliebig viel Speicher allokieren, solange es der Adressbereich zulässt; da ich ein 64-Bit-Ubuntu installiert habe, sollte ein Prozess ohne Probleme mehrere Terabyte anfordern können (ich hab das auch schon mal probiert - es ist lustig, wie Tools wie htop das dann nicht mehr richtig in ihren Tabellen anzeigen können 😀); der Prozess besitzt diesen Speicher dann allerdings natürlich nur virtuell; sobald er versucht, hineinzuschreiben, bekommt er dann Ärger, wenn dem System der physikalische Speicher ausgeht. Dies ist hier aber wohl nicht der Fall, wie meminfo zeigt.

Dass der Kernel ein Limit von möglichen Threads erreicht hat, ist ebenfalls ausgeschlossen, da ja andere Prozesse nochmal Unmengen von weiteren Threads starten dürfen. Also sehe ich hier ein eher künstliches Limit.

Seltsam ist auch, dass ich auf Google niemanden finde, der mein Problem zu haben scheint. Schon pid_max wurde nirgends empfohlen zu verändern, nur overcommit_memory. Das war bei mir aber entscheidend. Ich vermute irgendwie, dass Ubuntu da im Gedanken an typische Desktopeinsätze ein paar Variablen ein bisschen seltsam gesetzt hat.

Antworten |