Solaris et free()

Le
JKB
Bonsoir à tous,

Je suis en train de débugguer un programme de calcul sous Solaris
(il tourne sans problème sous Linux et FreeBSD). L'occupation
mémoire me semblait démentielle : sous Linux, il tourne dans 4 Go de
mémoire alors que dans la même configuration, il faut 8 Go sous
Solaris (!). Les tableaux temporaires de calcul ne sont jamais
libérés Je viens de m'apercevoir d'une note dans la page man de
free sous Solaris :

The argument to free() is a pointer to a block previously
allocated by malloc(), calloc(), or realloc(). After free()
is executed, this space is made available for further allo-
cation by the application, though not returned to the sys-
tem. Memory is returned to the system only upon termination
of the application. If ptr is a null pointer, no action
occurs. If a random number is passed to free(), the results
are undefined.

Ce qui veut dire si j'ai bien compris que free() ne libère pas
effectivement la mémoire pour la rendre au système, mais qu'il la
garde en réserve pour l'application (c'est un peu bizarre comme idée
lorsque cela contraint le système à swapper à mort).

Problème : chacun de mes processus de calcul parallèle fait 1.6 Go et
j'ai absolument besoin de libérer cette mémoire.

J'ai aussi vu qu'il existait un truc nommé libbsdmalloc. Est-ce que
cela pourrait répondre à mon problème ? Je n'ai rien vu dans les
pages man sur la libération effective de la mémoire. Suffit-il de
lier l'exécutable avev -lbsdmalloc ?

Sinon, une autre idée ? Merci de vos lumières

JKB

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
JKB
Le #17414871
Le 03-10-2008, ? propos de
Solaris et free(),
JKB ?crivait dans fr.comp.os.unix :
Bonsoir à tous,

Je suis en train de débugguer un programme de calcul sous Solaris
(il tourne sans problème sous Linux et FreeBSD). L'occupation
mémoire me semblait démentielle : sous Linux, il tourne dans 4 Go de
mémoire alors que dans la même configuration, il faut 8 Go sous
Solaris (!). Les tableaux temporaires de calcul ne sont jamais
libérés... Je viens de m'apercevoir d'une note dans la page man de
free sous Solaris :

The argument to free() is a pointer to a block previously
allocated by malloc(), calloc(), or realloc(). After free()
is executed, this space is made available for further allo-
cation by the application, though not returned to the sys-
tem. Memory is returned to the system only upon termination
of the application. If ptr is a null pointer, no action
occurs. If a random number is passed to free(), the results
are undefined.

Ce qui veut dire si j'ai bien compris que free() ne libère pas
effectivement la mémoire pour la rendre au système, mais qu'il la
garde en réserve pour l'application (c'est un peu bizarre comme idée
lorsque cela contraint le système à swapper à mort...).

Problème : chacun de mes processus de calcul parallèle fait 1.6 Go et
j'ai absolument besoin de libérer cette mémoire.

J'ai aussi vu qu'il existait un truc nommé libbsdmalloc. Est-ce que
cela pourrait répondre à mon problème ? Je n'ai rien vu dans les
pages man sur la libération effective de la mémoire. Suffit-il de
lier l'exécutable avev -lbsdmalloc ?



J'oubliais de préciser... Mon truc utilise pthread...

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
talon
Le #17416971
JKB
Bonsoir à tous,

Je suis en train de débugguer un programme de calcul sous Solaris
(il tourne sans problème sous Linux et FreeBSD). L'occupation
mémoire me semblait démentielle : sous Linux, il tourne dans 4 Go de
mémoire alors que dans la même configuration, il faut 8 Go sous
Solaris (!). Les tableaux temporaires de calcul ne sont jamais
libérés... Je viens de m'apercevoir d'une note dans la page man de
free sous Solaris :

The argument to free() is a pointer to a block previously
allocated by malloc(), calloc(), or realloc(). After free()
is executed, this space is made available for further allo-
cation by the application, though not returned to the sys-
tem. Memory is returned to the system only upon termination
of the application. If ptr is a null pointer, no action
occurs. If a random number is passed to free(), the results
are undefined.

Ce qui veut dire si j'ai bien compris que free() ne libère pas
effectivement la mémoire pour la rendre au système, mais qu'il la
garde en réserve pour l'application (c'est un peu bizarre comme idée
lorsque cela contraint le système à swapper à mort...).

Problème : chacun de mes processus de calcul parallèle fait 1.6 Go et
j'ai absolument besoin de libérer cette mémoire.

J'ai aussi vu qu'il existait un truc nommé libbsdmalloc. Est-ce que
cela pourrait répondre à mon problème ? Je n'ai rien vu dans les
pages man sur la libération effective de la mémoire. Suffit-il de
lier l'exécutable avev -lbsdmalloc ?

Sinon, une autre idée ? Merci de vos lumières...

JKB




Je crois -sauf erreur- qu'aucun OS ne libère effectivement la mémoire
quand on fait free(), que ce soit Linux, *BSD, ou Solaris. La mémoire
devient simplement réutilisable dans le programme comme te le dit ta
page man. Libérer effectivement la mémoire nécessiterait des appels
systèmes qui ruineraient les performances.
Celà étant, il est possible d'indiquer à l'OS de libérer des pages avec
madvise():

MADV_FREE Gives the VM system the freedom to free pages, and
tells the system that information in the specified page range is no
longer important. This is an efficient way of allowing malloc(3) to
free pages anywhere in the address space, while keeping the address
space valid. The next time that the page is referenced, the page might
be demand zeroed, or might contain the data that was there before the
MADV_FREE call. References made to that address space range will not
make the VM system page the information back in from backing store until
the page is modified again.

(sur FreeBSD-7).

--

Michel TALON
Che Averell
Le #17436671
JKB
Ce qui veut dire si j'ai bien compris que free() ne libère pas
effectivement la mémoire pour la rendre au système, mais qu'il la
garde en réserve pour l'application (c'est un peu bizarre comme idée
lorsque cela contraint le système à swapper à mort...).



Oui. En fait, c'est un peu plus compliqué que ça. malloc(3)/free(3) ne
sont que des fonctions de la libc, ce n'est pas ça qui va s'occuper de
gérer la mémoire avec le système, c'est autre chose. Et là, il y a
deux façon d'implémenter malloc/free.

La version historique, classique, consiste à demander au système un
peu en agrandissant le tas (HEAP), cela se fait en utilisant sbrk(2),
qui lui, est un appel système. A malloc de se débrouiller pour gérer
l'espace. L'inconvénient, c'est que quand cet espace devient
fragmenté, on va perdre de la mémoire. Et effectivement, dans ce mode,
il est rare que free(2) rende la mémoire au système en abaissant la
limite.

La solution, de nos jours, est d'utiliser mmap(2) et munmap(2) pour
implémenter respectivement malloc(3) et free(3). Grosso merdo, et sans
rentrer dans les détails, mmap et munmap sont des appels systèmes qui
correspondent directement à malloc et free. Dans ce cas, lorsque l'on
appelle free(3), l'appel à munmap(2) permet de rendre réellement la
mémoire au système.

Après, c'est là où on atteint les limites de mes connaissance :
normalement, la glibc2 utilise mmap(2) et munmap(2) pour implémenter
malloc(3) et free(3), mais sous solaris, je n'en sais fichtre rien.

Bon, tout ça, c'est ce que j'en ai compris de ce merdier, j'ai pu
looser grave...



Après, pour ton problème de taille qui double, ton solaris, ce ne
serait pas une version 64 bits par hasard ? Ou un compilo qui n'a pas
les même tailles d'int / long int ?
Publicité
Poster une réponse
Anonyme