
Envoyé par
Pol63
j'aurais bien voulu plus d'infos sur les "blob", ce qui rentre dans cette catégorie, et comment est gérée leur stack (vis à vis du pointeur d'allocation)
est-ce qu'une grande collection rentre dans ce cas ? ou juste les classes avec des dizaines de string ?
Il faut véritable que ce soit un objet en lui même qui dépasse une certaine limite (actuellement 85000 octets). Une classe avec des dizaines de string ne risque rien, car la classe n'aura qu'une dizaine de référence vers des strings. Et les références sont sur 4 ou 8 octets en fonction de l'architecture (32 ou 64 bits).
Par contre, une chaîne de caractères peut très bien dépasser cette limite. C'est courant si on charge en mémoire un fichier texte par exemple.
Pour les collections, c'est un peu la même chose. Je vais prendre le cas simple d'un tableau. Un tableau, pour dépasser cette limite, doit dépasser la limite de 85000 octets. Un tableau d'objet n'a que peu de chance de dépasser cette limite, dans la mesure où ce ne sont pas les objets eux-mêmes qui sont stockés au sein du tableau, mais des références vers ces objets. Il y a des cas où cela se fait facilement par contre. On peut citer :
- chargement d'un fichier en mémoire. Les tableaux de byte[] peuvent très vite grimper !
- gestion d'un cache ;
- des tableaux de structures.
Hormis c'est cas là, il faut dépasser le seuil théorie de 85000 / (taille référence) d'objets pour qu'un tableau soit considéré comme un blob, soit 21250 pour les architectures 32 bits et 10625 pour les architectures 64 bits. Ce qui laisse quand même un peu de marge.
Avec les structures, il est aussi possible de dépasser cette limite rapidement. En effet, dans la mesure où une structure est un type valeur, l'objet est directement stocké au sein du tableau. Si la structure est large, cette limite peut être dépassé. Par exemple, pour une structure qui aurait une taille de 1000 octets, il suffirait d'un tableau de 85 éléments pour qu'il soit considéré comme un blob.
Et le tas pour les blob est géré de la même manière que le tas managé "classique", à 2 différences près :
- les objets ne sont pas déplacés par défaut (car le déplacement de gros objets est coûteux) ;
- tous les objets sont de génération 2, c'est-à-dire qu'ils ne seront collectés que lorsque le ramasse-miettes fera une collecte complète. Une collecte des générations 0 et 1 n'a aucun incidence sur ce tas.

Envoyé par
Pol63
et aussi comment est choisit le nombre de générations à collecter ?
J'admet, c'est un sujet que je n'ai pas abordé dans l'article. J'avais décidé de le squizer pour diverses raisons.
Chaque génération dispose d'une taille seuil, au delà de laquelle la génération sera collectée.
Lorsque le ramasse-miettes se déclenche, il regarde la taille des différentes générations et la compare aux tailles seuils. Prenons la génération 1 et examinons les différents cas.
Si la taille de la génération 1 est inférieure à la taille seuil, alors la génération 1 n'est pas collectée. Seule la génération 0 le sera.
Si la taille de la génération 1 est supérieure à la taille seuil, alors la génération est collectée. Une fois la collecte terminée, le ramasse-miette peut faire évoluer les tailles seuil afin de s'adapter au comportement de l'application.
Cette modification des tailles seuil peut être aussi bien à la hausse qu'à la baisse. Par exemple, si le ramasse-miettes détecte qu'il y a énormément de petits objets à la durée de vie extrêmement courte qui sont créés, il peut décider de réduire le seuil de la génération 0, afin d'effectuer un nettoyage plus souvent, mais qui sera plus rapide (car moins d'objets à examiner à chaque fois).
Au final, je me demande si je ne vais pas écrire un autre article sur le sujet, afin de compléter certains points non abordé dans le premier !
0 |
0 |