On Mon, Jun 26, 2000 at 12:06:02PM +0200, Andre Schulze wrote:
genau: der prozess, der amok laeuft, sollte gekillt oder gestoppt werden. das ist das was man eigentlich erwartet.
Da ist leider aus Kernelsicht nicht so einfach feststellbar. Ich habe mir mal den Code angeschaut aber nicht komplett kapiert. Immerhin stellt er sicher dass nicht der init gekillt wird. Besser ware es, wenn es zu dieser Situation gar nicht(oder deutlich seltener) kommen wuerde. Dazu unten mehr.
wenig, normalerweise ist mein swap ja auch fast leer. bloed ist nur, das die anwendung spaeter auf bsd laufen soll. bsd ist sicher noch duemmer bei der handhabung von virtuellem speicher.
Wieso sollten die duemmer sein? Zumindest in dem Beispiel weiter unten verhält sich FreeBSD wie Solaris.
Es scheint noch keine sinnvoll funktionierende Lösung fuer diese Problem zu geben, die nicht massenhaft swap benötigt oder pessimistisch bei jedem fork() schon ein ENOMEM liefert, wenn der doppelte Platz fuer den Prozess nicht da ist.
der mysqld prozess ist ja auch schon da. ein fork() wird da nicht vom parent daemon gemacht.
Es geht darum, dass fork() noch gut geht, dem neuen Prozess beim Schreiben der Seiten aber der Speicher ausgeht, da dieser erst dann wirklich belegt wird. Ein Beispiel: (sorry fuer das ueberflussige Zeugs drin):
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/types.h>
int main() { void *p; pid_t pid; int size=200; /* in MB */
if ((p=malloc(size*1024*1024)) == 0) { perror("malloc()"); exit(-1); } if ( ((pid=fork()) == -1) ) { perror("fork()"); exit -2; } else if (pid == 0) { printf("child with %i MB\n", size); sleep(3); exit(0); } /* parent */ wait(); printf("free()\n"); free(p); return 0; }
Solaris 128MB + 200 MB freiem swap sagt: rf11@rncmm10:~> ./a.out fork(): Not enough space free() rf11@rncmm10:~> Aha. Er denkt sich was dabei. Nett.
Solaris 128MB + 480MB freiem swap laesst den fork dann zu.
So - nun zuLinux: Linux-2.2, 128MB + 180MB freier swap: rf11@rncmm11:~> free total used free shared buffers cached Mem: 127964 25616 102348 14728 1764 16580 -/+ buffers/cache: 7272 120692 Swap: 184708 0 184708 rf11@rncmm11:~> ./a.out child with 200 MB free() rf11@rncmm11:~> Er macht fork() problemlos, gibt also 400MB Speicher raus, obwohl nur ca. 300MB da sind. Wenn ich nun anfange die 400MB zu beschreiben gehen Prozesse flöten wie bei Andre der nfsd.
Genau dieses Verhalten stört mich bei Linux. Das MM arbeitet einfach zu optimistisch und faellt deshalb öfters auf die Knie als andere Systeme. Meiner Meinung nach sollte man bei fork() gleich den Platz im swap reservieren und geht so bestimmt 99% der Out-Of-Memory-Situationen in Linux aus dem Weg. Mit Optimierung hat das IMO nix zu tun. Und das alles uebrigens mit rf11@rncmm11:~> cat /proc/sys/vm/overcommit_memory 0 rf11@rncmm11:~> Das Flag ist sogar per default auf 0, scheint allerdings bei fork() völlig völlig sinnlos zu sein. Stell ich das Flag auf 1 kann ich sogar per malloc gleich mal 500MB auf o.g. Rechner ausfassen (siehe vm_enough_memory()). Die Stelle fuer fork() habe ich im Kernel noch nicht entdeckt.
Reinhard