Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
522 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  La tambouille interne du Garbage Collector... mystères !

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

La tambouille interne du Garbage Collector... mystères !

n°918157
oliv5
Pourquoi ? Parce que !
Posté le 08-12-2004 à 17:41:59  profilanswer
 

Salut tlm,
 
Je suis en train de finaliser une appli client-serveur, et je m'occupe d'optimiser les quantités de mémoires utilisées à droite et à gauche, en essayant de virer ce qui n'est pas utile.
Je viens de m'appercevoir d'une chose assez surprenante. Le serveur est un service windows, et à ce titre, ne créé pas de fenêtres. Cependant, pour pouvoir débugguer tranquillement, on peut le lancer en temps qu'application standart : il créé alors une fenetre de debug, avec un log, entre autre. A ce moment là, le serveur occupe environ 27Mo en ram. Si je réduit la fenetre, il n'occupe plus que 2Mo !!! Bon, bah, 25 Mo pour ma pauvre fenêtre, je trouvais ca un peu beaucoup, mais bon, passons, vu qu'elle ne servira pas dans le produit final.
Lorsque le serveur est lancé en temps que service, il occupe 20Mo, ce qui est un peu beaucoup à mon gout. Sachant que le Garbage Collector arrive à le réduire à 2Mo quand il s'agit d'une application, pourquoi est ce que mon service en occupe autant ?
 
J'ai essayé de placer des GC.Collect() à certains endroits, mais je ne vois strictement aucune différence, comme si cette instruction ne faisait rien.
 
Je me demande donc comment le garbage collector fonctionne ?
Va-t-il libérer de la mémoire si windows en a besoin, vu que visiblement, il y a 25 Mo occupés qui ne servent pas vraiment, ç première vue ?
Y-a-t'il un moyen pour lui faire lacher la mémoire non utilisée ?
 
Bref, comment fonctionne ce sacré GC ?

mood
Publicité
Posté le 08-12-2004 à 17:41:59  profilanswer
 

n°918519
oliv5
Pourquoi ? Parce que !
Posté le 09-12-2004 à 00:59:29  profilanswer
 

up

n°918524
Taz
bisounours-codeur
Posté le 09-12-2004 à 01:06:39  profilanswer
 

j'ai rien compris, si tu lances ton appli en mode debug depuis ton ide, biensur que ça va bouffer plus.
 
Ton problème, c'est que tu as une différence d'occupation mémoire entre ton appli lancée sans debug dans ton IDE et quand tu lances l'appli tout seule ?

n°918621
gedeon
Posté le 09-12-2004 à 10:28:50  profilanswer
 

Citation :

Bref, comment fonctionne ce sacré GC ?


Il y a un tres bon article dans le bouquin de patrick smacchia "Pratique de .NET et C#"
Le fonctionnement du GC est expliqué , mais gare aux maux de tete.

n°918648
HelloWorld
Salut tout le monde!
Posté le 09-12-2004 à 11:04:53  profilanswer
 

Un GC alloue un bon gros paquet de mémoire dès le début. A cela s'ajoute le JIT qui alloue de la mémoire pour compiler ton code au runtime, + les classes que tu utilises.  
C'est plutot tes 2Mo qui sont louches.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°918894
bjone
Insert booze to continue
Posté le 09-12-2004 à 15:38:55  profilanswer
 

c'est quoi qui fait 2 Mo, les pages allouées, ou le Working Set ? (pages utilisées à instant T en ram physique)

n°918924
oliv5
Pourquoi ? Parce que !
Posté le 09-12-2004 à 16:12:50  profilanswer
 

Taz a écrit :

j'ai rien compris, si tu lances ton appli en mode debug depuis ton ide, biensur que ça va bouffer plus.
 
Ton problème, c'est que tu as une différence d'occupation mémoire entre ton appli lancée sans debug dans ton IDE et quand tu lances l'appli tout seule ?


 
Non, c'est pas le mode debug, mais la release (qui possède une option de debug du type /debug en argument, et qui fait apparaitre une fenetre de log), lancée à la main.
Le pb, c'est que je comprends pas pourquoi quand je réduis la fenetre (ie, je clique sur le moins en haut a droite), imédiatement le GC libère 25 Mo.
 
Si il les libère, c'est qu'il en a pas besoin à cet instant. J'aimerais qu'il libère la mémoire non utilisée en permanance, en mode fenetré ou non fenétré, car 25 Mo non utilisé,c'est beaucoup. Or quand je fais des GC.Collect(), a priori bien placés, il ne libère rien (Il détruit bien mes objets, mais la quantité de RAM et de mémoire virtuelle utilisées ne changent pas). On reste à 26 Mo de ram utilisée.
 
Helloword, bjone : les 2Mo, ce sont ceux du working set, pas de la mémoire virtuelle (qui ne change pratiquement pas). Le working set passe de 26Mo à 2, on reste à 15 Mo pour la mémoire virtuelle.


Message édité par oliv5 le 09-12-2004 à 16:14:02
n°919924
oliv5
Pourquoi ? Parce que !
Posté le 10-12-2004 à 18:33:53  profilanswer
 

up

n°920036
nraynaud
lol
Posté le 10-12-2004 à 21:28:39  profilanswer
 

oliv5 a écrit :


J'ai essayé de placer des GC.Collect() à certains endroits, mais je ne vois strictement aucune différence, comme si cette instruction ne faisait rien.

sisi, normalement, on arrive à ralentir l'application avec ça. mais ça dépend, y'a des systèmes où elle est désactivée par défaut (donc elle ne ralentit rien).


---------------
trainoo.com, c'est fini
n°920039
oliv5
Pourquoi ? Parce que !
Posté le 10-12-2004 à 21:40:01  profilanswer
 

:)
 
Ca je m'en doute, mais à priori, je l'ai ai placés aux bons endroits (quand il y a des libérations massives de ressources).
 
En fait, si je vois une action : le GC détruit bien les objets apres le GC.Collect(), car on passe dans leurs destructeurs. Mais, au niveau de la mémoire employée, rien, pas un mouvement.
 
C'est énervant, car je vois d'ici le client me dire : "Votre service, il est bien mais il est pas discret, il pompe trop de mémoire."

mood
Publicité
Posté le 10-12-2004 à 21:40:01  profilanswer
 

n°920046
nraynaud
lol
Posté le 10-12-2004 à 21:51:23  profilanswer
 

ben tu me donnes de l'argent et je regarde ce qu'on peut y faire à ton bordel. Et je t'explique les choses au fur et à mesure.


---------------
trainoo.com, c'est fini
n°920083
Taz
bisounours-codeur
Posté le 10-12-2004 à 22:50:00  profilanswer
 

euh tu nous fais signe si t'arrives à faire tourner ton programme C# sur VM le tout avec 2Mo d'utilisation mémoire.

n°920085
nraynaud
lol
Posté le 10-12-2004 à 22:52:52  profilanswer
 

Taz > la feinte c'est de mettre la bibliothèque de classe dans un espace mémoire (partagé par toutes les applications si possible) qui n'est pas pris en compte par l'outil de reporting de la consomation mémoire :p


---------------
trainoo.com, c'est fini
n°920086
oliv5
Pourquoi ? Parce que !
Posté le 10-12-2004 à 22:53:00  profilanswer
 

Par curiosité, quels seraient tes tarifs pour un truc dans ce genre là ? (ie, optimiser une appli client-serveur + logiciel d'administration avec bdd ODBC, de la bonne programmation système de profondeur Win32)
 
De toute façons, je te le dis tout de suite, c'est un mauvais coup pour se faire de la thune : on bosse à 2, le contrat est rempli, mais le client nous embrouille sans cesse et on n'est pas d'accord sur les temps de développement nécéssaires pour faire "les petites(grosses) modifs" qu'il souhaite.
Et on a pas encore été payé pour le dev initial, d'ou la nécéssité de faire des versions de démo limités pour que le client puisse tester....
 
Bref, j'ai pas envie d'emmener un 3eme acteur dans ce bordel, quel qu'il soit.

n°920087
nraynaud
lol
Posté le 10-12-2004 à 22:57:09  profilanswer
 

oliv5 > on peut discuter de ça en privé si tu veux.


---------------
trainoo.com, c'est fini
n°920095
oliv5
Pourquoi ? Parce que !
Posté le 10-12-2004 à 23:02:57  profilanswer
 

Taz a écrit :

euh tu nous fais signe si t'arrives à faire tourner ton programme C# sur VM le tout avec 2Mo d'utilisation mémoire.


 
heu, voila mon signe.
 
Avant la reduction de la fenetre
http://olivkta.free.fr/temp/Avant.jpg
 
Apres la réduction de la fenetre
http://olivkta.free.fr/temp/Apres.jpg
 
La plupart du temps, ca remonte à 3-4 Mo dans les 10s qui suivent, puis dans la minute qui suit, de gros traitements se relancent et ca remonte encore bien sur, pour ne plus redescendre (alors que je libère bien ce qui ne sert plus).
 
edit : du jpg pour soulager votre BP.


Message édité par oliv5 le 10-12-2004 à 23:30:52
n°920097
nraynaud
lol
Posté le 10-12-2004 à 23:06:12  profilanswer
 

oliv5 > en général (tous sauf celui d'Eiffel à ma conaissance), les GCs ne libèrement pas le tas de mémoire qu'ils ont piqué au système. Y'a une raison un peut technique à ça : l'épinglage des objets utilisés dans le code natif.
 
C'est une des raisons pour lequelles il faut absolument faire collaborer les GCs avec la mémoire virtuelle (l'autre raison, c'est le swapping).


---------------
trainoo.com, c'est fini
n°920098
nraynaud
lol
Posté le 10-12-2004 à 23:07:12  profilanswer
 

oliv5> on peut avoir les titres des colones stp ? j'ai un gros doute d'un coup ....


---------------
trainoo.com, c'est fini
n°920108
chrisbk
-
Posté le 10-12-2004 à 23:10:43  profilanswer
 

des bmps, quelle bonne idée

n°920109
chrisbk
-
Posté le 10-12-2004 à 23:11:30  profilanswer
 

nraynaud a écrit :

oliv5> on peut avoir les titres des colones stp ? j'ai un gros doute d'un coup ....


 
que les 28 soient passé en swap ? [:ddr555]

n°920112
Taz
bisounours-codeur
Posté le 10-12-2004 à 23:13:57  profilanswer
 

déjà commence par utiliser System.GC.GetTotalMemory()

n°920117
nraynaud
lol
Posté le 10-12-2004 à 23:16:39  profilanswer
 

chrisbk a écrit :

que les 28 soient passé en swap ? [:ddr555]

y'a un 20Mo qui n'a pas bougé dans la colone d'à côté ...


---------------
trainoo.com, c'est fini
n°920126
oliv5
Pourquoi ? Parce que !
Posté le 10-12-2004 à 23:28:25  profilanswer
 

j'arrive avec les colonnes :)
les 20Mo c'est la mémoire virtuelle.
 
Edit :
 
dsl pour les bmp, c'est fait à l'arrache.
Voila les colonnes associées :
 
http://olivkta.free.fr/temp/colonnes.jpg
 
 
System.GC.GetTotalMemory() : Extrait le nombre d'octets qu'il est actuellement prévu d'allouer.
 
Kesako ? ca va m'indiquer quoi ? (msdn pas clair là)

n°920133
nraynaud
lol
Posté le 10-12-2004 à 23:37:25  profilanswer
 

heu, c'est louche la mémoire utilisée supérieure à la mémoire virtuelle utilisée, mais j'ai pareil sur mon PC aussi, y'a une explication à ça ?


---------------
trainoo.com, c'est fini
n°920134
chrisbk
-
Posté le 10-12-2004 à 23:38:08  profilanswer
 

nraynaud a écrit :

heu, c'est louche la mémoire utilisée supérieure à la mémoire virtuelle utilisée, mais j'ai pareil sur mon PC aussi, y'a une explication à ça ?


 
vi, t'additionnes les deux

n°920135
Taz
bisounours-codeur
Posté le 10-12-2004 à 23:38:46  profilanswer
 

oui, tu lis l'aide et tu vois qu'il s'agirait des pages résidentes en mémoire.

n°920159
HelloWorld
Salut tout le monde!
Posté le 11-12-2004 à 00:29:08  profilanswer
 

Utilise Process Explorer
http://www.sysinternals.com/ntw2k/ [...] cexp.shtml
View->Select Columns...->.Net
Tu as pas mal d'options intéressantes, comme le temps passé dans le GC, l'utilisation des 3 types de mémoire du GC, la mémoire allouée, ...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°920169
oliv5
Pourquoi ? Parce que !
Posté le 11-12-2004 à 00:58:03  profilanswer
 

j'ai déjà essayé mais je vois pas grand chose bouger quand se produit soit le processus de garbage collection ou qd je réduis la fenetre.
 
Au passage, je vois pas ce que tu appelle les 3 types de mémoire du GC. (je vois, dans procexp, le tas, le working set et la mémoire virtuelle, mais bon c'est pas à ca que tu fais allusion non ?)
 
Tout ce que je vois, c'est que le "working set" (j'ai une vague idée de ce que c'est) passe de beaucoup de Mo (ca dépends qd on fait le test, mais au max ce sont 25 Mo) à 3 lorsque je réduis la fenetre. Le % de temps passé dans le GC, monte de 0.15 à 1 à ce moment là avant de retomber.
Le reste des paramètres (virtual size, heap bytes, allocated bytes/sec) reste stable.
 
En revanche qd se produit le GC.Collect(), ya rien qui bouge!
 
Un petite question : je vois que le tas (heap bytes) passe progressivement de 1Mo à 2, puis revient à 1. Le GC alloue les objets a cet endroit là ??? (je comprend plus rien, car si c'est le cas, pkoi ca bouge pas lors de la libération par gc.collect() ?

n°920173
Taz
bisounours-codeur
Posté le 11-12-2004 à 01:03:47  profilanswer
 

t'as essayé System.GC.GetTotalMemory()  ?
 
parce que là on commence par se demander si ton problème ce n'est pas plutôt la lecture des informations et leur exactitudes.

n°920180
the real m​oins moins
Posté le 11-12-2004 à 01:23:44  profilanswer
 

bah c'est des screenshots du task manager ça non? [:totozzz]

n°920188
oliv5
Pourquoi ? Parce que !
Posté le 11-12-2004 à 01:34:53  profilanswer
 

oui "the real moins moins", c'est le taskmanager, tu veux celles de procexp ? (en jpg cette fois).
 
Edit : hop, vla les images
 
Avant la reduction de la fenetre :
http://olivkta.free.fr/temp/Avant2.jpg
 
Après :
http://olivkta.free.fr/temp/Apres2.jpg
 
(c'est la ligne en jaune)
 
Taz : je fous ca avant et apres GC.Collect() et je te dis ca. Pour l'exactitude des infos, je vous donne ce que je vois. J'aurais du mal a faire mieux, a part si j'ai raté une info qquepart.


Message édité par oliv5 le 11-12-2004 à 01:43:39
n°920195
oliv5
Pourquoi ? Parce que !
Posté le 11-12-2004 à 01:58:09  profilanswer
 

Bon, voila un premier résultat :
 
Value 1 : 610596     2: 610596
 
1) c'est avant le GC.Collect()
2) c'est apres. A croire que ya rien a libéré. Pourtant juste avant, on ferme une socket, on détruits les objets associés (ie on les mets a null, ya pas d'autres références) et on vide un objet dataset :
 
monDataset.Clear();  
monDataset.AcceptChanges();
 
Comme il était plein d'informations diverses et variés (un tas de chaines de caractères), ca m'étonne que rien ne soit libéré.
 
Je vais en mettre ailleurs dans le code pour voir ce que ca dit. Mais je doute de ce GetTotalMemory(), car déjà, je pige pas la doc associée...
 
Edit: je verrais demain, il est tard là. bn tt le monde.


Message édité par oliv5 le 11-12-2004 à 01:58:39
n°920203
HelloWorld
Salut tout le monde!
Posté le 11-12-2004 à 03:22:09  profilanswer
 

Citation :

Au passage, je vois pas ce que tu appelle les 3 types de mémoire du GC. (je vois, dans procexp, le tas, le working set et la mémoire virtuelle, mais bon c'est pas à ca que tu fais allusion non ?)


Non. Le GC sectorise les objets en 3 parties en fonction de leur durée de vie (résistance au garbage collecting). C'est expliqué dans l'article de Richter sur le GC:
http://msdn.microsoft.com/msdnmag/ [...] fault.aspx
et pour le 1°:
http://msdn.microsoft.com/msdnmag/ [...] fault.aspx
 
Depuis process explorer double clic sur le process, tu as tout le détail de sa mémoire dans l'onglet .Net (.Net CLR memory). Fait une comparaison des différents total mémoire utilisés avant/après.
 
Mais, après lecture complète du post...
Ne te fie pas à la colonne Utilisation Mémoire. Ton screenshot montre d'ailleurs que c'est naze, car elle dépasse la VM (même si la VM n'est pas la taille totale). C'est parce que ça prend en compte la mémoire partagée, c.a.d n'importe quelle dll mappée dans 2 process ou + et comptabilisée 2 fois ou +.
http://blogs.msdn.com/greggm/archi [...] 60078.aspx
Fie toi à la colonne VM memory, qui indique 20 Mo dans les 2 cas... Cette colonne représente la taille mémoire privée à ton process, et c'est pratiquement identique dans tes 2 exemples.
 
La colonne du working set size (Util. memoire) désigne la taille de la RAM physique accessible (et non pas réservée) à ton process, c'est à dire les pages physiques qu'il peut lire sans provoquer de fault.
Le working set est géré en accordéon par Windows, et cette gestion peut être influencée via SetProcessWorkingSetSize. Quand il a besoin de mémoire, Windows analyse les process et détermine ceux qui vont être swappés suivant différentes règles (idle depuis un certains temps, plus gros que les autres, ...). Il me parrait normal qu'un processus dont les fenêtres ont été minimisées soit considéré comme candidat au swapping.
Par contre j'avais pas noté que cet ajustement de working set (ou plutot sa forte diminution) était effectué en cas de minimisation de fenêtre, même si la mémoire est largement libre et que le swap est désactivé comme c'est le cas chez moi. Je pensais que c'était fait quand y'avait besoin de place, et apparement non, c'est pas tout à fait ça. Ca serait préventif, et surtout un working set brutalement diminué ne veut pas forcément dire que les pages ont été swappées et que leur prochain accès sera synonyme de page faults, mais juste qu'elles sont candidates à un swapping. Enfin c'est comme ça que j'interprète les choses.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°920209
Taz
bisounours-codeur
Posté le 11-12-2004 à 09:01:11  profilanswer
 

bon, ben moi je vois plus de problème

n°920538
ToxicAveng​er
Posté le 11-12-2004 à 18:04:15  profilanswer
 

place tes using aux bons endroits (pas avant le namespace donc), ca appellera les dispose automatiquement des que les objets ne seront plus utiles...

n°920556
oliv5
Pourquoi ? Parce que !
Posté le 11-12-2004 à 18:33:03  profilanswer
 

ToxicAvenger a écrit :

place tes using aux bons endroits (pas avant le namespace donc), ca appellera les dispose automatiquement des que les objets ne seront plus utiles...


 
Ca a une influence ? J'avoue que j'y connais rien. Qu'est ce que ca change ?
 

Code :
  1. using System.Text;
  2. namespace MonNamespace
  3. {
  4.   ...
  5. }


 

Code :
  1. namespace MonNamespace
  2. {
  3.    using System.Text;
  4.    ...
  5. }


 

Citation :

bon, ben moi je vois plus de problème.


 
Alors, ce serait normal. Voila ce que je comprend : quand je lance le client, il y a pas mal de mémoire de réservée en interne pour les traitements d'initialisation, donc pas mal de pages sont réservées.
Par la suite, on libère beaucoup des objets alloués initialement. Le GC passe derriere, détruit les objets, la mémoire occupée diminue mais le nombre de pages réservées reste identique.
 
Merci HelloWorld pour ces explications.

n°920559
chrisbk
-
Posté le 11-12-2004 à 18:39:28  profilanswer
 

using(truc machin=bidule() {
 
}

n°920573
oliv5
Pourquoi ? Parce que !
Posté le 11-12-2004 à 18:56:35  profilanswer
 

Ha oui, c'est pas con, je vais voir si ca pourrait améliorer les choses. merci

n°920637
HelloWorld
Salut tout le monde!
Posté le 11-12-2004 à 20:12:39  profilanswer
 

Citation :

Voila ce que je comprend : quand je lance le client, il y a pas mal de mémoire de réservée en interne pour les traitements d'initialisation, donc pas mal de pages sont réservées.


Quand tu lances le programme il détient la fenêtre qui a le focus, => c'est le thread prioritaire par rapport aux autres, et comme presque toute la mémoire est allouée au moment de son lancement, son working set suit la progression et la colonne Mem. utilisée traduit cette évolution. A ce moment, cette colonne & la colonne MV doivent se valoir.

Citation :

Par la suite, on libère beaucoup des objets alloués initialement. Le GC passe derriere, détruit les objets, la mémoire occupée diminue mais le nombre de pages réservées reste identique.


La mémoire diminue d'un point de vue .Net, mais pas forcément d'un point de vue Windows.
Y'a un truc que tu ne sembles pas avoir pigé : la mémoire collectée par le GC est libérée d'un point de vue .Net, mais pas forcément d'un point de vue systeme. On te l'a dit, un GC libére rarement la mémoire système qu'il a alloué. En pratique il le fait, mais par gros palliers. Si a chaque fois qu'un objet .Net était collecté et libérait 1Ko le GC les rendait au système, ça serait affreusement lent. Tu peux avoir totalement libéré la mémoire dans ton programme .Net, le GC conservera quand même les 10/20 Mo inutilisés.


Message édité par HelloWorld le 11-12-2004 à 20:17:22

---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°920639
HelloWorld
Salut tout le monde!
Posté le 11-12-2004 à 20:16:05  profilanswer
 

Au passage nraynaud te l'a dit, appeler GC.Collect() peut effectivement libérer plus vite la mémoire (mais elle le sera de toute façons), mais ça se paye en temps d'exécution. L'opération de garbage collecting n'est pas gratuite. C'est expliqué dans l'article de Richter.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  La tambouille interne du Garbage Collector... mystères !

 

Sujets relatifs
Recherche interneinformation sur les foreign keys - nom interne
Quel langage utilsé pour afficher un planning sur un réseau tv internecréation d'un moteur de recherche interne
erreur Oracle ORA-00600: code erreur interne, argumentsLien interne a une table
lien interneAvis sur un code (classe interne inside)
Moteur de recherche interne script ???moteur de recherche interne api google
Plus de sujets relatifs à : La tambouille interne du Garbage Collector... mystères !


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR