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