begin process at 2010 02 10 03:53:46
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

.NET

 > LES RÉFÉRENCES FAIBLES

LES RÉFÉRENCES FAIBLES


 Information sur la source

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :.NET Source .NET ( DotNet ) Classé sous :Weak References, Références faibles, mémoire, garbage collector Niveau :Initié Date de création :02/10/2007 Vu / téléchargé :4 561 / 96

Auteur : yoannd

Ecrire un message privé
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note


 Description

Cliquez pour voir la capture en taille normale
Il arrive parfois qu'il faille faire un choix entre performances, et consommation mémoire. Les références faibles sont justement ici pour nous éviter à faire ce choix. Elles permettent de ne garder en mémoire un (gros) objet que si l'espace mémoire est suffisant.

Exemple :
Je fais une visionneuse d'images. Au clic sur l'image 1, on va chercher sur le disque dur le contenu bitmap de celle-ci pour la mettre en RAM, puis on l'affiche dans un picture box.
Au clic sur l'image 2, le même process est utilisé : Récupération depuis le disque dur + mise en RAM + affichage.
Mais si je reclique sur l'image 1, il est dommage de rechercher l'image depuis le disque dur... le mieux pour la rapidité serait d'aller la chercher depuis la RAM... Le problème est que l'on ne va pas laisser en RAM toutes les images sous prétexte que l'utilisateur à cliqué une fois dessus...

Nous allons donc charger chaque image dans une référence faible, dès que l'utilisateur aura cliqué dessus. Ainsi, la seconde fois que l'on va cliquer sur une image elle sera soit :
- chargée depuis la RAM,
- chargée depuis le disque dur car le garbage collector aura considéré qu'il était nécessaire de "désaturer" l'espace mémoire.

Nous avons donc réussi à trouver, grâce aux références faibles, un compromis simple entre rapidité et consommation mémoire.

En résumé, pour utiliser les weak references sur un objet, il faut que :
- L'objet en question ne soit pointé QUE par cette référence faible,
(ET SURTOUT)
- L'objet puisse être récupéré (ou reconstitué, ou désérialisé, ou ce que vous voulez) depuis un autre endroit que la RAM, car si le garbage collector décide de vider la mémoire de votre objet, vous le perdez.

Pour l'exemple, vous pouvez le tester de la façon suivante :
Lancez l'exe, puis cliquez sur l'image 1 (apparition d'un log "Chargement depuis le disque dur"). Cliquez sur l'image 2 (apparition d'un log "Chargement depuis le disque dur"). Si vous cliquez une nouvelle fois sur l'image 1, aucune ligne de log ne doit normalement apparaître. Par contre, si vous laissez reposer le prog, et que vous faites autre chose qui consomme de la mémoire et que vous revenez sur le prog, alors de nouvelles lignes de log doivent apparaître pour signifier que les images sont rechargées depuis le disque dur.

Bon coding à tous !

Source

  • /// <summary>
  • /// Accesseur en lecture seule permettant de récupérer la donnée bmp du papier-peint.
  • /// </summary>
  • public Bitmap bmp{
  • get{
  • // Si la référence faible n'est pas
  • // instanciée ou si elle n'est plus active
  • if(refBitMap == null || !refBitMap.IsAlive){
  • // Chargement du bitmap depuis le disque
  • Bitmap buff = (Bitmap) Bitmap.FromFile(m_filePath);
  • // Stockage dans la référence faible
  • if(refBitMap == null)
  • refBitMap = new WeakReference(buff);
  • else
  • refBitMap.Target = buff;
  • // Levée d'un évènement car l'image a été chargée depuis le disque
  • if(onWeakReferenceLoaded != null) onWeakReferenceLoaded(this, EventArgs.Empty);
  • // On retourne l'image
  • return buff;
  • }else{
  • // Sinon, on retourne son contenu sans
  • // rechercher quoi que ce soit sur le disque dur.
  • return (Bitmap) refBitMap.Target;
  • }
  • }
  • }
		/// <summary>
		/// Accesseur en lecture seule permettant de récupérer la donnée bmp du papier-peint.
		/// </summary>
public Bitmap bmp{
	get{
		// Si la référence faible n'est pas
		// instanciée ou si elle n'est plus active
		if(refBitMap == null || !refBitMap.IsAlive){
			// Chargement du bitmap depuis le disque
			Bitmap buff = (Bitmap) Bitmap.FromFile(m_filePath);
					
			// Stockage dans la référence faible
			if(refBitMap == null)
				refBitMap = new WeakReference(buff);
			else
				refBitMap.Target = buff;
					
			// Levée d'un évènement car l'image a été chargée depuis le disque
			if(onWeakReferenceLoaded != null) onWeakReferenceLoaded(this, EventArgs.Empty);
					
			// On retourne l'image
			return buff;
		}else{
			// Sinon, on retourne son contenu sans
			// rechercher quoi que ce soit sur le disque dur.
			return (Bitmap) refBitMap.Target;
		}
	}
}

 Conclusion

Source éditée avec SharpDevelop et la version 2 du .net Framework.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture Source .NET (Dotnet) PIXEL SHADER - CRÉATION, UTILISATION, ET BINDING
Source avec Zip Source avec une capture Source .NET (Dotnet) CRÉATION ET ENVOI DE FICHIERS ZIPPÉS
Source avec Zip Source .NET (Dotnet) EXTENSION DES LISTES GÉNÉRIQUES (DESIGN PATTERN "DECORATEUR"...
Source avec Zip Source avec une capture Source .NET (Dotnet) UN PEU DE 3D AVEC XAML ET BLENDER
Source avec Zip Source avec une capture Source .NET (Dotnet) QUELQUES EFFETS EN XAML

 Sources de la même categorie

Source avec Zip CHAT SERVER-CLIENT par abderrahmenbilog
Source avec Zip Source avec une capture Source .NET (Dotnet) SIMULATION DE CONSOLE POUR WINDOWS MOBILE par originalcompo
Source avec Zip Source .NET (Dotnet) BASE DE DONNÉES EN XML par DanMor498
Source avec Zip Source avec une capture Source .NET (Dotnet) SIMPLECONV - APPLICATION DE CONVERSION MONÉTAIRE AVEC TAUX E... par Jeffrey_
Source avec Zip Source .NET (Dotnet) TRAITEUR D'IMAGE (MINI) par ycyril

 Sources en rapport avec celle ci

Source avec Zip Source .NET (Dotnet) INFOS SUR LA MEMOIRE par gg00xiv
Source avec Zip Source .NET (Dotnet) MÉMO C# par DrChal

Commentaires et avis

Commentaire de oximoron le 02/10/2007 12:09:59 10/10

Merci pour cette source cela peut être très utile.
Est ce que ce code marche avec le framework 1.1 ?
Autre question: c'est le garbage collector qui s'occupe de liberer de l'espace disque. Si j'ai une collection d'images en mémoire il qu'il doit liberer de la mémoire, sur quoi se base t'il pour supprimer une image ? la fréquence d'utilisation, au hasard, ... ?

Commentaire de Bidou le 02/10/2007 13:07:48 administrateur CS

Compatible depuis le framework 1.0 jusqu'au 3.0.
Le fonctionnement du garbage collector est assez complexe, mais ce qui certain, c'est qu'il ne dispose pas des ressources tant qu'il reste une référence dessus (et encore heureux...!)

Commentaire de yoannd le 02/10/2007 14:32:28

Ce que dit Bidou est vrai : le garbage collector a un fonctionnement assez complexe. J'ai envie de dire, connaitre son fonctionnement est bon pour la culture générale, mais finallement, le principal, c'est qu'il fasse bien son travail (et qu'il ne supprime pas des références utilisées ailleurs que par des références faibles). Je ne pourrais donc pas te dire pour quels critères un élément en référence faible est supprimé de la mémoire, désolé :-)

D'ailleurs, je ne sais pas si tu as remarqué, mais si tu laisses l'appli en plan quelques minutes sur une image "A", et que tu cliques sur un autre image "B", alors il y a un rechargement depuis le disque pour "B". Si tu reviens tout de suite après sur "B", il n'y a pas de rechargement en mémoire, tout simplement parceque la référence vers l'obet bmp était maintenue par... le PictureBox ! Hé oui ;-)

Commentaire de coq le 06/10/2007 18:13:24 administrateur CS

"c'est le garbage collector qui s'occupe de liberer de l'espace disque"
Non, il ne touche pas au disque.

"J'ai envie de dire, connaitre son fonctionnement est bon pour la culture générale, mais finallement, le principal, c'est qu'il fasse bien son travail"
Oui et non ^^ : le problème en ne connaissant pas un minimum son fonctionnement, c'est que la personne à tendance à le prendre pour la solution magique lui permettant de ne plus se soucier du fait qu'un code alloue de la mémoire à tour de bras alors qu'une autre façon de faire l'aurait éviter : si le risque de fuite est écarté, celui de l'impact sur les performances ne l'est pas : le GC qui libère est un GC qui consomme du temps (le problème de la concaténarion de chaines en est un exemple courant)
.

Commentaire de yoannd le 07/10/2007 06:00:43

Coq, je suis tout à fait d'accord avec toi. Et le coup des concaténations de chaines est un très bon exemple !
Ainsi, un développeur qui garde plein de références inutiles vers des instances de classes va pourrir la mémoire, sans que le garbage collector ne puisse rien y faire...
Enfin toujours est-il que je ne pense pas pouvoir expliquer dans les moindres détails les rouges de ce mécanisme, car il semble assez complexe.
Pour preuve, j'ai récement écrit un petit outil de revue de code (le langage de ces fichiers était du nsdk). Après parsing, j'avais une hiérarchie d'objets : un objet "fichier nsdk" contient des descriptions de segments, des constantes, ou des méthodes, un objet "méthode" contient des variables, ect... je ne vais pas détailler ici l'ensemble des objets, mais toujours est-il que le résultat en mémoire était assez important : et je ne pouvais rien libérer car l'objet de ma revue de code était de voir si certaines méthodes dans plusieurs fichiers n'étaient pas suffisamment identiques pour être mutualisées. Toujours est-il qu'au cours du chargement des fichiers, la jauge mémoire grimpait, puis descendait un peu (???) puis continuait à monter, puis redescendait un peu... alors qu'aucune libération mémoire n'était faite pendant ce temps (bien au contraire). Le garbage collector ou le framework font-ils de la compression des données en mémoire si ça se gate ? Bref, c'est un phénomène assez bizarre (que j'avais déjà eu l'occasion de rencontrer, et qui montre, à mon avis, que cette gestion de la mémoire n'est pas si anodine que ça...

enfin en conclusion ; le garbage collector, c'est bien, mais faut quand même faire un minimum gaffe à ce qu'on fait ^^

Commentaire de oximoron le 07/10/2007 09:34:31

""c'est le garbage collector qui s'occupe de liberer de l'espace disque"
Non, il ne touche pas au disque."
Je voulais bien sûr dire mémoire et pas disque, je pensais mémoire mais j'ai écris disque :p

Commentaire de coq le 07/10/2007 09:37:20 administrateur CS

Ba le code des types que tu utilises pour la lecture fait des allocations aussi, et d'autres choses vivent en dehors de ton code de traitement :-)
Il n'y a à ma connaissance aucun mécanisme de compression.
Et fait attention à ce que tu utilises pour tes mesures : http://www.itwriting.com/dotnetmem.php

Commentaire de coq le 07/10/2007 09:38:46 administrateur CS

oximoron : oui oui, j'avais compris, je disais ça surtout pour éviter que les lecteurs soient induits en erreur :-)

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Utilisation mémoire sous Win XP avec .NET :( [ par Raptorx ] Salut à tous !!Je viens de terminer un projet en C# et je suis étonné de voir dans le gestionnaire de tache la mémoire qu'il utilise (8Mo)!!!Je croyai Gestion de l'espace mémoire [ par moontek ] Salut,donc je viens de faire une petite recherche sur le forum concernant la place en mémoire de certains programme C#, pour ma part mon programme pre récupérer le pourcentage de mémoire disponible en C# [ par jermo ] Bonjour,j'aimerai afficher dans mon application le pourcentrage de mémoire disponible sur le pc.comment faire?merci d'avance! PB avec mémoire qui gonfle [ par PsyCaDi ] Bonjour,J'ai fait un programme avec une fonction et un timer qui me sort la position de la souris mais j'ai un pb de mémoire utilisée qui gonfle. Au l Mémoire partagee [ par keerigan ] Bonjour J'aimerais savoir s'il est possible de gerer un fichier "memoire partagee" tout comme le faisait C++si oui quelles fonctions permet de faire c Conseil sur l'utilisation de la mémoire :utilisation de static [ par taoetc ] Bonjour , voila, j'ai besoin d'avoir une liste de constante accessible par plusieurs classes.J'ai donc décidé de créer une classe qui contiendrait t Liberaton d'espace mémoire [ par Athalus ] J'ai une winform dans laquelle j'utilise un tableau de tableau et lorsque je ferme cette form l'espace utilisé en memoire par les tableaux ne se libe ca va exploser !!!! [ par revlis ] Bonjours, Je suis en train de developper un outils de planning.je me trouve face a un calendrier contenant plusieurs tache.Chaque jours du calendrier Taille du processus d'une appli en C# [ par zobio ] Bonjour à tous, Je débute en c# après une expérience approfondie du C++.Je travaille depuis kkes jours sur une appli du genre media player.J'ai consta Libération de la mémoire dans une appli [ par zobio ] Salut tout le monde.J'ai une petite question concernant la m&#233;moire utilis&#233;e par une appli .NetEn fait vous avez certainement remarqu&#233; q


Nos sponsors


Sondage...

Comparez les prix


HTC Magic

Entre 429€ et 429€

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,484 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales