OVH Cloud OVH Cloud

fuite mémoires

6 réponses
Avatar
mohamed92000
Bonjour =E0 tous;

Voila je suis entrein de passer Purify sur mon application (C++,
librairie ILOG). Purify m'indique qu'il y'a des fuites de m=E9moires
importante mais pas dans mon code, voici quelques lignes de Purify :

[I] MPK: Potential memory leak of 1548288 bytes from 18 blocks
allocated in PeekMessageA [USER32.dll]
[W] MLK: Memory leak of 589824 bytes from 28 blocks allocated in
PeekMessageA [USER32.dll]
Memory leak of 113200 bytes from 190 blocks allocated in GetTextFaceA
[GDI32.dll]
Memory leak of 91568 bytes from 173 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
Potential memory leak of 21840 bytes from 8 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
[I] MPK: Potential memory leak of 8720 bytes from 2 blocks allocated in
GetTextFaceA [GDI32.dll]
[W] MLK: Memory leak of 7712 bytes from 12 blocks allocated in
DocumentEvent [WINSPOOL.DRV]
Memory leak of 5312 bytes from 9 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
[I] MPK: Potential memory leak of 3096 bytes from 3 blocks allocated in
PerfClose [WINSPOOL.DRV]
[W] MLK: Memory leak of 1680 bytes from 2 blocks allocated in
SearchPathW [KERNEL32.dll]
[W] MLK: Memory leak of 1680 bytes from 2 blocks allocated in
ClearCustData [OLEAUT32.dll]

Sachant que cette perte de m=E9moire est cumulable avec le nombre
d'excution(des fonctionnalit=E9s sur lesquelles je passe purify).

Questions :

a) Comment faire pour d=E9tourner ces fuites.
b)Est ce qu'on recup=E8re les fuites de m=E9moires une fois qu'on quitte
l'application?. Si la r=E9ponse est oui, alors dans ce cas pourquoi se
prendre la t=EAte =E0 faire des delete sur tous les objets allou=E9s avant
quitter de l'application(biensur qu'on on redemmare la machine on
recupere la m=E9moire l=E0 c'est claire).

Merci Par Avance

6 réponses

Avatar
James Kanze
wrote:

Voila je suis entrein de passer Purify sur mon application
(C++, librairie ILOG). Purify m'indique qu'il y'a des fuites
de mémoires importante mais pas dans mon code, voici quelques
lignes de Purify :


[I] MPK: Potential memory leak of 1548288 bytes from 18 blocks
allocated in PeekMessageA [USER32.dll]
[W] MLK: Memory leak of 589824 bytes from 28 blocks allocated in
PeekMessageA [USER32.dll]
Memory leak of 113200 bytes from 190 blocks allocated in GetTextFaceA
[GDI32.dll]
Memory leak of 91568 bytes from 173 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
Potential memory leak of 21840 bytes from 8 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
[I] MPK: Potential memory leak of 8720 bytes from 2 blocks allocated in
GetTextFaceA [GDI32.dll]
[W] MLK: Memory leak of 7712 bytes from 12 blocks allocated in
DocumentEvent [WINSPOOL.DRV]
Memory leak of 5312 bytes from 9 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
[I] MPK: Potential memory leak of 3096 bytes from 3 blocks allocated in
PerfClose [WINSPOOL.DRV]
[W] MLK: Memory leak of 1680 bytes from 2 blocks allocated in
SearchPathW [KERNEL32.dll]
[W] MLK: Memory leak of 1680 bytes from 2 blocks allocated in
ClearCustData [OLEAUT32.dll]


Sachant que cette perte de mémoire est cumulable avec le nombre
d'excution(des fonctionnalités sur lesquelles je passe purify).


Questions :


a) Comment faire pour détourner ces fuites.


Ça dépend de l'application. Typiquement, la solution la plus
simple, c'est d'utiliser le collecteur de Boehm. Mais je vois
que tu utilises une bibliothèque tièrce ; parfois, ça rend
l'utilisation du GC de Boehm plus difficile.

Sinon, la solution est simple : il faut faire un delete des
objets en question:-).

En fait, je soupçonne, sans vraiment connaître ILog, que tu n'as
pas respecté les contraints qu'elle impose, qu'il y a des
fonctions documentées à renvoyer des objets dynamiques que tu
dois supprimer, et que tu ne l'as pas fait. Purify n'indique
qu'où l'objet a été allouée, non où on aurait dû la libérer.
Régarde bien donc la documentation des fonctions ci dessus, pour
voir si ce n'est pas à toi de libérer ce qu'elles renvoient.

b)Est ce qu'on recupère les fuites de mémoires une fois qu'on
quitte l'application?


Ça dépend du système (et ce qu'on entend par « quitter
l'application » -- et à la rigueur, ce qu'on entend par « fuite
de mémoire »). Sous les Unix (et je crois aussi Windows), la
plupart des ressources allouées à un processus sont libérées
quand le processus est terminé. La mémoire, en tout cas, ainsi
que des locks, etc. (mais pas par exemple les fichiers
temporaires -- qui sont aussi « de la mémoire »).

Si la réponse est oui, alors dans ce cas pourquoi se prendre
la tête à faire des delete sur tous les objets alloués avant
quitter de l'application(biensur qu'on on redemmare la machine
on recupere la mémoire là c'est claire).


Parce qu'on veut être sûr, même en cas de portage à un système
qui ne les libère pas. Et parce que le delete fait plus que
simplement libère la mémoire -- il appelle aussi les
destructeurs, dont certains peuvent avoir pour responsibilité de
libérer d'autres ressources, par exemple, de supprimer le
fichier temporaire.

Mais selon le cas, si on sait qu'on va terminer tout de suite,
et qu'on n'utilise pas d'autres ressources que la mémoire (ou
qu'on s'arrange autrement à les libérer), il arrive qu'on
termine sans libérer de la mémoire exprès. Seulement, de nos
jours, il y a de moins en moins de programmes qui termine après
un travail simple. Ou bien, on a affaire à un serveur, qui
tourne sans s'arrêter, 24 heures sur 24, sept jours par semaine,
ou bien, il s'agit d'un client graphique, que l'utilisateur
laisse actif plus ou moins longtemps, pour effectuer on ne sait
pas combien d'opérations. Une fuite de mémoire dans de telles
applications est une erreur fatale.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Avatar
mohamed92000
tout d'abord merci de votre réponde;
je répond juste au :

Sinon, la solution est simple : il faut faire un delete des
objets en question:-).
Purify fait réference à des objets dans des libraires comme

USER32.dll et autres dont j'y pas accés au code source. Purify
n'indique pas les objets à moi si non j'aurais fait le delete je suis
d'accord dans ce cas
merci


wrote:

Voila je suis entrein de passer Purify sur mon application
(C++, librairie ILOG). Purify m'indique qu'il y'a des fuites
de mémoires importante mais pas dans mon code, voici quelques
lignes de Purify :

[I] MPK: Potential memory leak of 1548288 bytes from 18 blocks
allocated in PeekMessageA [USER32.dll]
[W] MLK: Memory leak of 589824 bytes from 28 blocks allocated in
PeekMessageA [USER32.dll]
Memory leak of 113200 bytes from 190 blocks allocated in GetTextFaceA
[GDI32.dll]
Memory leak of 91568 bytes from 173 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
Potential memory leak of 21840 bytes from 8 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
[I] MPK: Potential memory leak of 8720 bytes from 2 blocks allocated in
GetTextFaceA [GDI32.dll]
[W] MLK: Memory leak of 7712 bytes from 12 blocks allocated in
DocumentEvent [WINSPOOL.DRV]
Memory leak of 5312 bytes from 9 blocks allocated in
DocumentPropertySheets [WINSPOOL.DRV]
[I] MPK: Potential memory leak of 3096 bytes from 3 blocks allocated in
PerfClose [WINSPOOL.DRV]
[W] MLK: Memory leak of 1680 bytes from 2 blocks allocated in
SearchPathW [KERNEL32.dll]
[W] MLK: Memory leak of 1680 bytes from 2 blocks allocated in
ClearCustData [OLEAUT32.dll]

Sachant que cette perte de mémoire est cumulable avec le nombre
d'excution(des fonctionnalités sur lesquelles je passe purify).

Questions :

a) Comment faire pour détourner ces fuites.


Ça dépend de l'application. Typiquement, la solution la plus
simple, c'est d'utiliser le collecteur de Boehm. Mais je vois
que tu utilises une bibliothèque tièrce ; parfois, ça rend
l'utilisation du GC de Boehm plus difficile.

Sinon, la solution est simple : il faut faire un delete des
objets en question:-).

En fait, je soupçonne, sans vraiment connaître ILog, que tu n'as
pas respecté les contraints qu'elle impose, qu'il y a des
fonctions documentées à renvoyer des objets dynamiques que tu
dois supprimer, et que tu ne l'as pas fait. Purify n'indique
qu'où l'objet a été allouée, non où on aurait dû la libérer.
Régarde bien donc la documentation des fonctions ci dessus, pour
voir si ce n'est pas à toi de libérer ce qu'elles renvoient.

b)Est ce qu'on recupère les fuites de mémoires une fois qu'on
quitte l'application?


Ça dépend du système (et ce qu'on entend par « quitter
l'application » -- et à la rigueur, ce qu'on entend par « fuite
de mémoire »). Sous les Unix (et je crois aussi Windows), la
plupart des ressources allouées à un processus sont libérées
quand le processus est terminé. La mémoire, en tout cas, ainsi
que des locks, etc. (mais pas par exemple les fichiers
temporaires -- qui sont aussi « de la mémoire »).

Si la réponse est oui, alors dans ce cas pourquoi se prendre
la tête à faire des delete sur tous les objets alloués avant
quitter de l'application(biensur qu'on on redemmare la machine
on recupere la mémoire là c'est claire).


Parce qu'on veut être sûr, même en cas de portage à un système
qui ne les libère pas. Et parce que le delete fait plus que
simplement libère la mémoire -- il appelle aussi les
destructeurs, dont certains peuvent avoir pour responsibilité de
libérer d'autres ressources, par exemple, de supprimer le
fichier temporaire.

Mais selon le cas, si on sait qu'on va terminer tout de suite,
et qu'on n'utilise pas d'autres ressources que la mémoire (ou
qu'on s'arrange autrement à les libérer), il arrive qu'on
termine sans libérer de la mémoire exprès. Seulement, de nos
jours, il y a de moins en moins de programmes qui termine après
un travail simple. Ou bien, on a affaire à un serveur, qui
tourne sans s'arrêter, 24 heures sur 24, sept jours par semaine,
ou bien, il s'agit d'un client graphique, que l'utilisateur
laisse actif plus ou moins longtemps, pour effectuer on ne sait
pas combien d'opérations. Une fuite de mémoire dans de telles
applications est une erreur fatale.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34



Avatar
James Kanze
wrote:
tout d'abord merci de votre réponde;
je répond juste au :


Sinon, la solution est simple : il faut faire un delete des
objets en question:-).



Purify fait réference à des objets dans des libraires comme
USER32.dll et autres dont j'y pas accés au code source.
Purify n'indique pas les objets à moi si non j'aurais fait le
delete je suis d'accord dans ce cas


Purify n'indique pas à qui sont les objets -- il ne peut pas le
savoir. Il indique qui les a alloué. Ce que je crois probable,
c'est que ce sont bien des objets alloués par la bibliothèque,
mais dont la bibliothèque a passé la responsibilité à toi. Comme
j'ai dit, il faut bien régarder la documentation de la
bibliothèque, pour voir s'il n'y a pas des cas où la
bibliothèque a renvoyé des objets en en passant la
responsibilité à toi, et que tu ne les a pas supprimés.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
Sylvain
wrote on 17/04/2006 14:16:

Purify fait réference à des objets dans des libraires comme
USER32.dll et autres dont j'y pas accés au code source. Purify
n'indique pas les objets à moi si non j'aurais fait le delete je suis
d'accord dans ce cas


user32 ne provoque aucune perte de mémoire (depuis le temps on l'aurait
vu sinon) par ses traitements propres, par contre tout ce qui est créé
par l'application en utilisant les API de user32 (principalement les
fonctions CreateXXX) doit être balancé par une libération (un appel à
DestroyXXX).

j'interprète votre log comme indiquant les fonctions ayant utilisé les
blocs perdus (moyennement util) savoir qui les a alloués (quelle source,
sinon quelle fonction) serait plus utile.

vous pourriez essayer une (bête) compil. par Visual Studio en activant
la détection de pertes de mémoires (opérateur DEBUG_NEW).

Sylvain.

Avatar
Sylvain
wrote on 17/04/2006 12:08:

[I] MPK: Potential memory leak of 1548288 bytes from 18 blocks
allocated in PeekMessageA [USER32.dll]


PeekMessage n'alloue rien, il ne fait que retourner un message un attente.

la boucle principale d'une appli. utilise une instance globale de MSG,
ici j'imagine que vous avez un process qui a alloué ce MSG, l'a pushé et
s'en est allé, il serait peu surprenant de lire dans la spec. du dit
process que le destinataire du msg doit désallouer ce msg.

Memory leak of 113200 bytes from 190 blocks allocated in GetTextFaceA
[GDI32.dll]


GetTextFace n'alloue rien, elle reçoit le buffer à utiliser (pour copier
le nom du typeface) et sa longueur; l'appelant peut utiliser un buffer
static sur la pile ou comme ici un buffer alloué, mais il faut dans ce
cas le deleter; faites une recherche sur les appels à cette fonction.

etc...

a) Comment faire pour détourner ces fuites.


"détourner" ? pour les corriger, il suffit de les localiser et de
corriger le code.

b)Est ce qu'on recupère les fuites de mémoires une fois qu'on quitte
l'application?. Si la réponse est oui, alors dans ce cas pourquoi se
prendre la tête à faire des delete sur tous les objets alloués avant
quitter de l'application.


hmmm, pourquoi aussi se "prendre la tête" à faire le traitement attendu,
à ne pas crasher aléatoirement, ...
si votre appli. sert si peu qu'on la quitte à peine lancée, pourquoi se
"prendre la tête" avec un truc qui ne sert finalement à rien.

Sylvain.

Avatar
James Kanze
Sylvain wrote:
wrote on 17/04/2006 14:16:


Purify fait réference à des objets dans des libraires comme
USER32.dll et autres dont j'y pas accés au code source.
Purify n'indique pas les objets à moi si non j'aurais fait
le delete je suis d'accord dans ce cas



user32 ne provoque aucune perte de mémoire (depuis le temps on
l'aurait vu sinon) par ses traitements propres,


On ne peut jamais exclure que dans un cas extrèmement
particulier d'utilisation...

Mais je doute effectivement que ce soit le cas ici.

par contre tout ce qui est créé par l'application en utilisant
les API de user32 (principalement les fonctions CreateXXX)
doit être balancé par une libération (un appel à DestroyXXX).


Attention en revanche, s'il s'en sert à travers de la
bibliothèque ILog. Pour lui, l'utilisation doit être
transparente, et c'est aux conventions d'ILog qu'il faut qu'il
adhère. Il y a sûrement quelque chose d'équivalent, mais ça
risque de s'appelait différemment.

j'interprète votre log comme indiquant les fonctions ayant
utilisé les blocs perdus (moyennement util) savoir qui les a
alloués (quelle source, sinon quelle fonction) serait plus
utile.


Purify indique où la bloc a été alloué. En revanche, c'est tout
à fait possible que certains blocs déclarés comme fuites
potentielles n'en sont pas en réalité -- si, par exemple, la
fonction alloue de la mémoire une fois à son premier appel.

vous pourriez essayer une (bête) compil. par Visual Studio en
activant la détection de pertes de mémoires (opérateur
DEBUG_NEW).


S'il a déjà Purify, je doute que ça lui apporte plus
d'informations.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34