OVH Cloud OVH Cloud

Allouer plus de mémoire que disponible

76 réponses
Avatar
Rémi Moyen
Salut,

J'ai une question sur la mani=E8re dont se comporte un programme sous
Linux, en C++, quand on essaye d'allouer plus de m=E9moire que
disponible sur le syst=E8me. =C0 la base, l'op=E9rateur new lance dans ce
cas-l=E0 une exception et c'est =E0 moi de la rattraper et de la traiter,
tr=E8s bien.

Mais mon probl=E8me est de savoir si, par derri=E8re, le noyau essaye
d'allouer toute la m=E9moire avant de se rendre compte qu'il n'en a pas
assez de disponible, ou est-ce qu'il fait d'abord une v=E9rification
avant de se lancer l=E0-dedans ?

Dans le cas o=F9 la m=E9moire est sur de la RAM, =E7a ne change probablement
pas grand chose (en perception par l'utilisateur), mais si il y a du
swap, est-ce que le noyau va faire swapper tout ce qu'il peut pendant
une heure avant de se rendre compte qu'il lui manque 42 octets ?

Si c'est le cas, alors j'imagine que j'ai int=E9r=EAt =E0 impl=E9menter
quelques checks rapides sur la m=E9moire disponible avant de commencer =E0
allouer des blocs de 1 Go (=E7a m'arrive...), sinon mes utilisateurs
risquent de ne pas trop aimer devoir attendre longtemps, et swapper
tout les autres programmes, avant de s'entendre dire qu'il n'y a pas
assez de m=E9moire pour faire ce qu'ils veulent ! Et dans ce cas-l=E0
encore, y'a-t-il une mani=E8re plus ou moins "standard" de v=E9rifier "=E0
la main" la m=E9moire disponible ?

Et accessoirement, j'imagine que diff=E9rents OS peuvent se comporter
diff=E9remment de ce point de vue, donc est-ce pareil pour SunOS ?
IRIX ? (les deux autres syst=E8mes que je suis susceptible d'utiliser)

Merci d'avance !
--
R=E9mi Moyen

10 réponses

Avatar
Jean-Louis Liagre
Jean-Louis Liagre wrote in message
<45d6e2dc$0$3702$:
Dans la limite de l'espace disque disponible si. (swapon, swap -a ou
équivalent).


Ce n'est pas créer, ça.


Ajouter du swap permet d'augmenter à chaud la taille de la mémoire
virtuelle.

J'ai aussi lu:

http://developers.sun.com/solaris/articles/subprocess/subprocess.html
On y apprend que sous Linux, même quand l'overcommit est désactivé, il y
est quand même (!),


On y apprend surtout que Greg Nakhimovsky ne lit pas bien les docs.


Il les lit très bien, quand il y en a.

Quand il n'y en a pas, il reste le code source, qui indique clairement
que même quand l'overcommit est désactivé, il l'est en fait encore.

Extrait de:

http://lxr.linux.no/source/Documentation/vm/overcommit-accounting?v=2.6.18


13 2 - Don't overcommit. The total address space commit
14 for the system is not permitted to exceed swap + a
15 configurable percentage (default is 50) of physical RAM.
16 Depending on the percentage you use, in most situations
17 this means a process will not be killed while accessing
18 pages but will receive errors on memory allocation as
19 appropriate.


Il donc faut mettre un autre paramètre à zéro pour inhiber la chose.


Avatar
Nicolas George
Jean-Louis Liagre wrote in message
<45d743d4$0$29728$:
13 2 - Don't overcommit. The total address space commit
14 for the system is not permitted to exceed swap + a
15 configurable percentage (default is 50) of physical RAM.
16 Depending on the percentage you use, in most situations
17 this means a process will not be killed while accessing
18 pages but will receive errors on memory allocation as
19 appropriate.

Il donc faut mettre un autre paramètre à zéro pour inhiber la chose.


Non. Relis bien, et fais le calcul. Ça permet d'allouer au total strictement
moins que la mémoire virtuelle totale disponible.

Avatar
Michel Talon
Rémi Moyen wrote:


Oui. Il faut voir comment est implémenté new(), mais il me semble
qu'en général (et surtout pour les petits blocs) il écrit dans toutes
les pages.


OK. Je vais essayer de creuser ça du côté de new.



En fait, je viens de voir un post dans colds qui précise ce point:


new calls the default constructor, which here, set the
value to 0, and hence touches the page,
and then requires it physically. If you ask for insane amounts,
you'll get a C++ exception.

Effectivement, donc, appeler new conduit à mettre toutes les pages en
mémoire, ce qui ne veut pas dire qu'elles vont y rester, si on n'applique
pas mlock() en plus.

~


Avatar
Rémi Moyen
Michel Talon wrote:

Oui. Il faut voir comment est implémenté new(), mais il me semble
qu'en général (et surtout pour les petits blocs) il écrit dans toutes
les pages.
OK. Je vais essayer de creuser ça du côté de new.




En fait, je viens de voir un post dans colds qui précise ce point:


new calls the default constructor, which here, set the
value to 0, and hence touches the page,
and then requires it physically. If you ask for insane amounts,
you'll get a C++ exception.

Effectivement, donc, appeler new conduit à mettre toutes les pages en
mémoire, ce qui ne veut pas dire qu'elles vont y rester, si on n'applique
pas mlock() en plus.


OK, super ! Merci d'avoir trouvé ça, c'est exactement la réponse à ma
question. Je vais tester un peu pour vérifier, mais je pense avoir tous
les éléments pour essayer de faire un truc relativement supportable pour
les utilisateurs compte-tenu de mes contraintes.

Merci encore pour toutes ces explications.
--
Rémi Moyen



Avatar
Jean-Louis Liagre
Nicolas George wrote:
Jean-Louis Liagre wrote in message
<45d743d4$0$29728$:
13 2 - Don't overcommit. The total address space commit
14 for the system is not permitted to exceed swap + a
15 configurable percentage (default is 50) of physical RAM.
16 Depending on the percentage you use, in most situations
17 this means a process will not be killed while accessing
18 pages but will receive errors on memory allocation as
19 appropriate.

Il donc faut mettre un autre paramètre à zéro pour inhiber la chose.


Non. Relis bien, et fais le calcul. Ça permet d'allouer au total strictement
moins que la mémoire virtuelle totale disponible.



Non. Ton calcul est faux. La mémoire virtuelle totale disponible est
toujours inférieure à la somme de la RAM et du swap, et rien ne garantit
qu'elle soit supérieure ou égale à "la taille du swap + 50% de la taille
de la RAM", d'où les réserves et le flou du commentaire: "depending" ...
"in most situations".

Linux n'est donc pas capable de gérer en temps réel ce seuil de manière
exacte, et propose à la place un paramètre pas très sérieux.


Avatar
Nicolas George
Jean-Louis Liagre wrote in message
<45d888f2$0$14276$:
Non. Ton calcul est faux. La mémoire virtuelle totale disponible est
toujours inférieure à la somme de la RAM et du swap,


J'aimerais bien que tu illustres cette affirmation pour le moins osée.

d'où les réserves et le flou du commentaire: "depending" ...
"in most situations".


Ces réserves correspondent au cas où le noyau lui-même a besoin urgemment
d'une grande quantité de mémoire. C'est excessivement rare.

Avatar
Jean-Louis Liagre
Nicolas George wrote:
Jean-Louis Liagre wrote in message
<45d888f2$0$14276$:
Non. Ton calcul est faux. La mémoire virtuelle totale disponible est
toujours inférieure à la somme de la RAM et du swap,


J'aimerais bien que tu illustres cette affirmation pour le moins osée.


Certains périphériques s'allouent de la RAM avant que le noyau démarre,
par exemple des cartes graphiques.

Le noyau lui-meme, utilise pour son propre compte de la RAM, et
exclusivement de la RAM. Cette mémoire n'est pas de la mémoire
virtuelle. Le noyau met jamais cette mémoire en swap.


d'où les réserves et le flou du commentaire: "depending" ...
"in most situations".


Ces réserves correspondent au cas où le noyau lui-même a besoin urgemment
d'une grande quantité de mémoire.


Non.


Avatar
Nicolas George
Jean-Louis Liagre wrote in message
<45d8a992$0$20040$:
Certains périphériques s'allouent de la RAM avant que le noyau démarre,
par exemple des cartes graphiques.

Le noyau lui-meme, utilise pour son propre compte de la RAM, et
exclusivement de la RAM. Cette mémoire n'est pas de la mémoire
virtuelle. Le noyau met jamais cette mémoire en swap.


Oui, mais dans ce cas, le noyau ne la compte pas non plus dans la RAM
physique disponible, du coup, on revient à la case départ.

Non.


Ben si.

Avatar
Jean-Louis Liagre
Nicolas George wrote:
Jean-Louis Liagre wrote in message
<45d8a992$0$20040$:
Certains périphériques s'allouent de la RAM avant que le noyau démarre,
par exemple des cartes graphiques.

Le noyau lui-meme, utilise pour son propre compte de la RAM, et
exclusivement de la RAM. Cette mémoire n'est pas de la mémoire
virtuelle. Le noyau met jamais cette mémoire en swap.


Oui, mais dans ce cas, le noyau ne la compte pas non plus dans la RAM
physique disponible, du coup, on revient à la case départ.



C'est une interprétation plausible, mais qui ne correspond pas à ce qui
est écrit ici:

The total address space commit for the system is not permitted to exceed
swap + a configurable percentage (default is 50) of physical RAM.

Il n'est pas fait ici allusion a un espace *disponible* de swap ou de
RAM. J'en déduis donc qu'il s'agit de la taille totale du swap plus la
moitié de la RAM installée. Il est en effet écrit "Physical RAM", pas
"Available RAM".


Avatar
Nicolas George
Jean-Louis Liagre wrote in message
<45d8c514$0$3286$:
C'est une interprétation plausible, mais qui ne correspond pas à ce qui
est écrit ici:

The total address space commit for the system is not permitted to exceed
swap + a configurable percentage (default is 50) of physical RAM.

Il n'est pas fait ici allusion a un espace *disponible* de swap ou de
RAM. J'en déduis donc qu'il s'agit de la taille totale du swap plus la
moitié de la RAM installée. Il est en effet écrit "Physical RAM", pas
"Available RAM".


Linux a l'habitude de ne pas _du tout_ comptabiliser la mémoire utilisée
directement par le coeur du noyau (la plus grande partie étant la table des
pages). C'est comme ça. Par exemple, dans /proc/meminfo, MemTotal ne la
prend pas en compte. Dans ces conditions, il est absolument évident pour
quiconque un peu au courant que la mention « physical RAM » doit
s'interpréter à cette aune, et simplement par opposition à swap.