Maison > Article > développement back-end > Principe du mécanisme de collecte des ordures .Net (2)
Texte original en anglais : Jeffrey Richter
Compilé par : Zhao Yukai
Lien http://www.php.cn/
L'article précédent a présenté les principes de base du garbage collection .Net et le mécanisme interne du garbage collection pour exécuter la méthode Finalize ; dans cet article, nous examinons les objets de référence faibles, les générations, le garbage collection multi-thread et les gros objets. compteurs de performances liés au traitement et au garbage collection.
Commençons par les objets de référence faibles. Les objets de référence faibles peuvent réduire la pression de la mémoire causée par les objets volumineux.
Références faibles
Lorsque l'objet racine du programme pointe vers un objet, l'objet est accessible et le garbage collector ne peut pas le récupérer. C'est ce qu'on appelle une référence forte à l'objet. Le contraire des références fortes sont les références faibles. Lorsqu'il y a une référence faible sur un objet, le garbage collector peut récupérer l'objet, mais il permet également au programme d'accéder à l'objet. Que se passe-t-il? Veuillez lire ci-dessous.
S'il n'y a que des références faibles sur un objet et que le garbage collector est en cours d'exécution, l'objet sera recyclé. Si l'objet est accédé plus tard dans le programme, l'accès échouera. D'un autre côté, pour utiliser un objet faiblement référencé, le programme doit d'abord faire une référence forte à l'objet avant que le garbage collector ne récupère l'objet, alors (après avoir eu une référence forte) le garbage collector le fera. Cet objet ne peut pas être recyclé. C'est un peu alambiqué, utilisons un morceau de code pour l'expliquer :
void Method() { //创建对象的强引用 Object o = new Object(); // 用一个短弱引用对象弱引用o. WeakReference wr = new WeakReference(o); o = null; // 移除对象的强引用 o = wr.Target; //尝试从弱引用对象中获得对象的强引用 if (o == null) { // 如果对象为空说明对象已经被垃圾回收器回收掉了 } else { // 如果垃圾回收器还没有回收此对象就可以继续使用对象了 } }
Pourquoi avons-nous besoin d'objets faibles ? Car certaines données sont faciles à créer, mais nécessitent beaucoup de mémoire. Par exemple : vous disposez d'un programme qui doit accéder à tous les dossiers et noms de fichiers sur le disque dur de l'utilisateur ; vous pouvez accéder au disque de l'utilisateur pour générer des données une fois lorsque le programme a besoin de ces données pour la première fois. Une fois les données générées, vous. peut accéder aux données dans la mémoire. Les données sont utilisées pour obtenir les données du fichier utilisateur au lieu de lire le disque pour obtenir des données à chaque fois. Cela peut améliorer les performances du programme.
问题是这个数据可能相当大,需要相当大的内存。如果用户去操作程序的另外一部分功能了,这块相当大的内存就没有占用的必要了。你可以通过代码删除这些数据,但是如果用户马上切换到需要这块数据的功能上,你就必须重新从用户的磁盘上构建这个数据。弱引用为这种场景提供了一种简单有效的方案。
当用户切换到其他功能时,你可以为这个数据创建一个弱引用对象,并把对这个数据的强引用解除掉。这样如果程序占用的内存很低,垃圾回收操作就不会触发,弱引用对象就不会被回收掉;这样当程序需要使用这块数据时就可以通过一个强引用来获得数据,如果成功得到了对象引用,程序就没有必要再次读取用户的磁盘了。
WeakReference类型提供了两个构造函数:
WeakReference(object target); WeakReference(object target, bool trackResurrection);
target参数显然就是弱引用要跟踪的对象了。trackResurrection参数表示当对象的Finalize方法执行之后是否还要跟踪这个对象。默认这个参数是false。有关对象的复活请参考这里。
Pour plus de commodité, les références faibles qui ne suivent pas l'objet réanimé sont appelées « références faibles courtes » ; tandis que les références faibles qui suivent les objets réanimés sont appelées « références faibles longues ». Si l'objet n'implémente pas la méthode Finalize, alors la référence faible longue et la référence faible courte sont exactement les mêmes. Il est fortement recommandé d'éviter d'utiliser des références longues et faibles. Les références longues et faibles vous permettent d'utiliser des objets ressuscités dont le comportement peut être imprévisible.
Une fois que vous utilisez WeakReference pour référencer un objet, il est recommandé de définir toutes les références fortes de cet objet sur null ; si une référence forte existe, le garbage collector ne pourra jamais récupérer l'objet pointé par la référence faible ; .
Lorsque vous souhaitez utiliser une référence faible à l'objet cible, vous devez créer une référence forte pour l'objet cible. C'est très simple. Utilisez simplement l'objet a = weekRefer.Target;. .Référence faible Il ne peut continuer à être utilisé que s'il n'est pas vide. S'il est faiblement vide, cela signifie que l'objet a été recyclé par le garbage collector et que l'objet doit être réacquis par d'autres méthodes.
Implémentation interne des références faibles
De la description précédente, nous pouvons déduire que les objets de référence faibles sont définitivement traités différemment des objets généraux. De manière générale, si un objet fait référence à un autre objet, il s'agit d'une référence forte et le garbage collector ne peut pas recycler l'objet référencé. Cependant, ce n'est pas le cas de l'objet WeakReference. L'objet auquel il fait référence peut être recyclé.
Pour bien comprendre le fonctionnement des objets faibles, nous devons également jeter un œil au tas géré. Il existe deux structures de données internes sur le tas géré. Leur seul rôle est de gérer les références faibles : on peut les appeler tables de références faibles longues et tables de références faibles courtes ;
Au début du programme en cours d'exécution, les deux tables sont vides. Lorsque vous créez un objet WeakReference, l'objet n'est pas alloué sur le tas géré, mais un emplacement vide (Empty Slot) est créé dans la table des objets faibles. Les objets de référence faibles courts sont placés dans la table d'objets faibles courts, et les objets de référence faibles longs sont placés dans la table de références faibles longues.
Une fois qu'un emplacement vide est trouvé, la valeur de l'emplacement vide sera définie sur l'adresse de l'objet cible de référence faible ; évidemment, les objets dans les tables d'objets faibles longs et courts ne seront pas considérés comme l'objet racine du application. Le garbage collector ne collectera pas de données dans les tables d'objets faibles longues et courtes.
Jetons un coup d'œil à ce qui se passe lorsque le garbage collection est exécuté :
1. Le garbage collector construit un graphe d'objets accessible
2. table d'objets faibles. , si l'objet pointé dans la table d'objets faibles ne se trouve pas dans le graphique d'objets accessible, alors l'objet est marqué comme un objet poubelle, puis le pointeur d'objet dans la table d'objets courte est défini sur null
3. Analyse du garbage collector File d'attente de terminaison (voir ci-dessus), si l'objet dans la file d'attente ne se trouve pas dans le graphique des objets accessibles, l'objet est déplacé de la file d'attente de terminaison vers la file d'attente Freachable. À ce stade, l'objet est marqué comme accessible. objet et n'est plus une poubelle
4. Le garbage collector analyse la longue table de référence faible. Si l'objet dans la table ne se trouve pas dans le graphique des objets accessibles (le graphique des objets accessibles inclut les objets dans la file d'attente Freachable), définissez le pointeur d'objet correspondant dans la table des objets de référence longue sur null
5. Le garbage collector déplace l'accessible. object
Une fois que vous avez compris comment fonctionne le garbage collector, il est facile de comprendre comment fonctionnent les références faibles. L'accès à la propriété Target de WeakReference amène le système à renvoyer le pointeur de l'objet cible dans la table des objets faibles. S'il est nul, cela signifie que l'objet a été recyclé.
Les références faibles courtes ne suivent pas les résurrections, ce qui signifie que le garbage collector peut vérifier si l'objet pointé dans la table de références faibles est un objet poubelle avant d'analyser la file d'attente de finalisation.
La référence longue et faible suit l'objet ressuscité, ce qui signifie que le ramasse-miettes doit définir le pointeur dans la table de référence faible sur null après avoir confirmé que l'objet est recyclé.
Génération :
En ce qui concerne le garbage collection .Net, les programmeurs c ou c peuvent se demander s'il y aura des problèmes de performances dans la gestion de la mémoire de cette manière. Les développeurs de GC peaufinent constamment le garbage collector pour améliorer ses performances. La génération est un mécanisme permettant de réduire l’impact du garbage collection sur les performances. Le garbage collector supposera que les affirmations suivantes sont vraies lorsqu'il travaille :
1. Plus un objet est récent, plus son cycle de vie est court.
2. Plus l'objet est ancien, plus sa durée de vie est courte. Le cycle de l'objet est long.
3. Les nouveaux objets sont généralement plus susceptibles d'avoir des relations de référence avec les nouveaux objets
4. La compression d'une partie du tas est plus rapide que la compression de l'ensemble du tas
Bien sûr, de nombreuses recherches ont prouvé que les hypothèses ci-dessus sont fondées. De nombreuses procédures sont établies. Parlons donc de la façon dont ces hypothèses affectent le travail du garbage collector.
Au moment de l'initialisation du programme, il n'y a aucun objet sur le tas géré. À l'heure actuelle, les objets nouvellement ajoutés au tas géré sont de génération 0. Comme le montre la figure ci-dessous, les objets de génération 0 sont les objets les plus jeunes et ils n'ont jamais été vérifiés par le garbage collector.
Figure 1 Objets de génération 0 sur le tas géré
Maintenant, si d'autres sont ajoutés au tas Objets, le garbage collection sera déclenché lorsque le tas se remplira. Lorsque le garbage collector analyse le tas géré, il crée un graphique d'objets poubelles (blocs violet clair dans la figure 2) et d'objets non poubelles. Tous les objets qui n'auront pas été recyclés seront déplacés et compressés vers le bas du tas. Ces objets qui n'ont pas été recyclés deviennent des objets de génération 1, comme le montre la Figure 2
Figure 2 Managed Heap Generation 0 et 1 objets sur le
Lorsque plus d'objets sont alloués sur le tas, les nouveaux objets sont placés dans la zone de génération 0. Si le tas de génération 0 se remplit, un garbage collection sera déclenché. À ce stade, les objets survivants deviennent des objets de génération 1 et sont déplacés vers le bas du tas ; une fois le garbage collection effectué, les objets survivants des objets de génération 1 seront promus en objets de génération 2 et déplacés et compressés. Comme le montre la figure 3 :
Figure 3 Objets de génération 0, 1 et 2 sur le tas géré
2代对象是目前垃圾回收器的最高代,当再次垃圾回收时,没有回收的对象的代数依然保持2.
垃圾回收分代为什么可以优化性能
如前所述,分代回收可以提高性能。当堆填满之后会触发垃圾回收,垃圾回收器可以只选择0代上的对象进行回收,而忽略更高代堆上的对象。然而,由于越年轻的对象生命周期越短,因此,回收0代堆可以回收相当多的内存,而且回收所耗的性能也比回收所有代对象要少得多。
这是分代垃圾回收的最简单优化。分代回收不需要便利整个托管堆,如果一个根对象引用了一个高代对象,那么垃圾回收器可以忽略高代对象和其引用对象的遍历,这会大大减少构建可达对象图的时间。
如果回收0代对象没有释放出足够的内存,垃圾回收器会尝试回收1代和0代堆;如果仍然没有获得足够的内存,那么垃圾回收器会尝试回收2,1,0代堆。具体会回收那一代对象的算法不是确定的,微软会持续做算法优化。
多数堆(像c-runtime堆)只要找到足够的空闲内存就分配给对象。因此,如果我连续分配多个对象时,这些对象的地址空间可能会相差几M。然而在托管堆上,连续分配的对象的内存地址是连续的。
前面的假设中还提到,新对象之间更可能存在相互引用关系。因此新对象分配到连续的内存上,你可以获得就近引用的性能优化(you gain performance from locality of reference)。这样的话很可能你的对象都在CPU的缓存中,这样CPU的很多操作就不需要去存取内存了。
微软的性能测试显示托管堆的分配速度比标准的win32 HeapAlloc方法还要快。这些测试也显示了200MHz的Pentium的CPU做一次0代回收时间可以小于1毫秒。微软的优化目的是让垃圾回收耗用的时间小于一次普通的页面错误。
使用System.GC类控制垃圾回收
类型System.GC运行开发人员直接控制垃圾回收器。你可以通过GC.MaxGeneration属性获得GC的最高代数,目前最高代是定值2.
你可以调用GC.Collect()方法强制垃圾回收器做垃圾回收,Collect方法有两个重载:
void GC.Collect(Int32 generation) void GC.Collect()
第一个方法允许你指定要回收那一代。你可以传0到GC.MaxGeneration的数字做参数,传0只做0代堆的回收,传1会回收1代和0代堆,而传2会回收整个托管堆。而无参数的方法调用GC.Collect(GC.MaxGeneration)相当于整个回收。
在通常情况下,不应该去调用GC.Collect方法;最好让垃圾回收器按照自己的算法判断什么时候该调用Collect方法。尽管如此,如果你确信比运行时更了解什么时候该做垃圾回收,你就可以调用Collect方法去做回收。比如说程序可以在保存数据文件之后做一次垃圾回收。比如你的程序刚刚用完一个长度为10000的大数组,你不再需要他了,就可以把它设置为null然后执行垃圾回收,缓解内存的压力。
GC还提供了WaitForPendingFinalizers方法。这个方法简单的挂起执行线程,知道Freachable队列中的清空之后,执行完所有队列中的Finalize方法之后才继续执行。
GC还提供了两个方法用来返回某个对象是几代对象,他们是
Int32 GC.GetGeneration(object o); Int32 GC.GetGeneration(WeakReference wr)
第一个方法返回普通对象是几代,第二个方法返回弱引用对象的代数。
下面的代码可以帮助你理解代的意义:
private static void GenerationDemo() { // Let's see how many generations the GCH supports (we know it's 2) Display("Maximum GC generations: " + GC.MaxGeneration); // Create a new BaseObj in the heap GenObj obj = new GenObj("Generation"); // Since this object is newly created, it should be in generation 0 obj.DisplayGeneration(); // Displays 0 // Performing a garbage collection promotes the object's generation GC.Collect(); obj.DisplayGeneration(); // Displays 1 GC.Collect(); obj.DisplayGeneration(); // Displays 2 GC.Collect(); obj.DisplayGeneration(); // Displays 2 (max generation) obj = null; // Destroy the strong reference to this object GC.Collect(0); // Collect objects in generation 0 GC.WaitForPendingFinalizers(); // We should see nothing GC.Collect(1); // Collect objects in generation 1 GC.WaitForPendingFinalizers(); // We should see nothing GC.Collect(2); // Same as Collect() GC.WaitForPendingFinalizers(); // Now, we should see the Finalize // method run Display(-1, "Demo stop: Understanding Generations.", 0); } class GenObj{ public void DisplayGeneration(){ Console.WriteLine(“my generation is ” + GC.GetGeneration(this)); } ~GenObj(){ Console.WriteLine(“My Finalize method called”); } }
垃圾回收机制的多线程性能优化
Dans la partie précédente, j'ai expliqué l'algorithme GC et l'optimisation, puis la prémisse de la discussion était dans une situation à thread unique. Dans un programme réel, il est probable que plusieurs threads fonctionnent ensemble et que plusieurs threads manipulent ensemble les objets sur le tas géré. Lorsqu'un thread déclenche le garbage collection, tous les autres threads doivent suspendre l'accès à tous les objets référencés (y compris les objets référencés sur leur propre pile), car le garbage collector peut déplacer l'objet et modifier son adresse mémoire.
Ainsi, lorsque le garbage collector commence à recycler, tous les threads exécutant du code managé doivent se bloquer. Le runtime dispose de plusieurs mécanismes différents pour suspendre en toute sécurité les threads afin d'effectuer le garbage collection. Je ne vais pas m'étendre sur le mécanisme interne de cette pièce. Cependant, Microsoft continuera de modifier le mécanisme de garbage collection pour réduire la perte de performances causée par le garbage collection.
Les paragraphes suivants décrivent le fonctionnement du garbage collector dans une situation multithread :
Interrompre complètement l'exécution du code Lorsque le garbage collection commence à s'exécuter, suspendez tous les threads de l'application. Le garbage collector enregistre ensuite la position suspendue du thread dans une table générée par le compilateur juste à temps (JIT). Le garbage collector est chargé d'enregistrer la position suspendue du thread dans la table et d'enregistrer l'objet en cours d'accès ainsi que l'emplacement. où l'objet est stocké (dans les variables, les registres du CPU, etc.)
Détournement : le ramasse-miettes peut modifier la pile du thread pour faire pointer l'adresse de retour vers une méthode spéciale. Lorsque la méthode actuellement exécutée revient, cette méthode spéciale le fera. exécuter et suspendre le thread. Cette façon de modifier le chemin d'exécution du thread est appelée détournement du thread. Une fois le garbage collection terminé, le thread reviendra à la méthode précédemment exécutée.
Point de sécurité : lorsque le compilateur JIT compile une méthode, il peut insérer un morceau de code à un certain moment pour déterminer si le GC est bloqué. Si tel est le cas, le thread se bloque en attendant la fin du garbage collection, puis le thread. relance l'exécution. Les endroits où le compilateur JIT insère la vérification du code GC sont appelés « points sûrs »
Notez que le détournement de thread permet aux threads qui exécutent du code non managé de s'exécuter pendant le garbage collection. Ce n'est pas un problème si le code non managé n'accède pas aux objets sur le tas géré. Si ce thread exécute actuellement du code non managé puis revient à l'exécution de code managé, le thread sera piraté et ne poursuivra pas son exécution tant que le garbage collection n'est pas terminé.
En plus du mécanisme de centralisation que je viens de mentionner, le garbage collector présente d'autres améliorations pour améliorer l'allocation et le recyclage de la mémoire des objets dans les programmes multithread.
Allocations sans synchronisation : dans un système multithread, le tas de génération 0 est divisé en plusieurs zones et un thread utilise une zone. Cela permet à plusieurs threads d'allouer des objets simultanément sans qu'un seul thread soit propriétaire exclusif du tas.
Collections évolutives : exécutez la version serveur du moteur d'exécution (MXSorSvr.dll) dans un système multithread. Le tas géré sera divisé en plusieurs zones différentes, une pour chaque processeur. Lorsque le recyclage est initialisé, chaque processeur exécute un thread de recyclage et chaque thread récupère sa propre zone. La version poste de travail du moteur d'exécution (MXCorWks.dll) ne prend pas en charge cette fonctionnalité.
Recyclage des gros objets
Cette section ne sera pas traduite. Il y a un article spécial qui en parle
Surveillance du garbage collection
Si vous avez installé le framework .Net, votre Il y aura. être un élément de mémoire .Net CLR dans le compteur de performances (Menu Démarrer - Outils d'administration - Entrée de performances). Vous pouvez sélectionner un programme dans la liste des instances à observer, comme indiqué dans la figure ci-dessous.
Les significations spécifiques de ces indicateurs de performance sont les suivantes :
Compteurs de performances |
Description |
# Octets dans tous les tas |
Affiche la somme des valeurs de compteur suivantes : compteur "Taille de tas de niveau 0", compteur de taille de tas "Niveau 1", taille de tas de niveau 2 et le compteur de taille de tas d'objets volumineux. Ce compteur indique la mémoire actuelle allouée sur le tas récupéré (en octets). |
# GC Handles (nombre de handles GC) |
Affiche la collecte des ordures dans utiliser Le nombre actuel de processus. Le garbage collection est le traitement des ressources en dehors du Common Language Runtime et de l’environnement d’hébergement. |
#Collections Gen 0 (nombre de recyclage niveau 2) |
Afficher depuis l'application Le nombre de fois où les objets de niveau 0 (c'est-à-dire les objets les plus récents et les plus récemment alloués) ont été récupérés depuis le démarrage du programme. Le garbage collection de niveau 0 se produit lorsqu'il n'y a pas suffisamment de mémoire disponible au niveau 0 pour satisfaire une demande d'allocation. Ce compteur est incrémenté à la fin du garbage collection de niveau 0. Le garbage collection de niveau supérieur inclut tous les garbage collection de niveau inférieur. Ce compteur est explicitement incrémenté lorsqu'un garbage collection de niveau supérieur (niveau 1 ou niveau 2) se produit. Ce compteur affiche la valeur observée la plus récente. La valeur du compteur _Global_ est inexacte et doit être ignorée. |
#Collections Gen 1 (nombre de recyclage 2ème niveau) |
Afficher depuis l'application Le nombre de fois où les objets de niveau 1 sont récupérés après le démarrage du programme. Ce compteur est incrémenté à la fin du garbage collection de niveau 1. Le garbage collection de niveau supérieur inclut tous les garbage collection de niveau inférieur. Ce compteur est explicitement incrémenté lorsque le garbage collection de niveau supérieur (niveau 2) se produit. Ce compteur affiche la valeur observée la plus récente. La valeur du compteur _Global_ est inexacte et doit être ignorée. |
# Collections Gen 2 (nombre de collections de niveau 2) |
Afficher depuis l'application Le nombre de fois où les objets de niveau 2 sont récupérés depuis le démarrage du programme. Ce compteur est incrémenté à la fin d'un garbage collection de niveau 2 (également appelé garbage collection complet). Ce compteur affiche la valeur observée la plus récente. La valeur du compteur _Global_ est inexacte et doit être ignorée. |
# GC induits (le nombre de GC provoqués) |
Affiche le GC dû to Nombre maximal de garbage collection effectués en raison d'appels explicites à .Collect. Il est pratique de laisser le garbage collector affiner la fréquence de ses collectes. |
Nombre d'objets épinglés (nombre d'objets épinglés) |
Affiche le dernier garbage collection Le numéro des objets épinglés rencontrés. Les objets épinglés sont des objets que le garbage collector ne peut pas déplacer en mémoire. Ce compteur suit uniquement les objets épinglés dans le tas qui sont en cours de récupération de place. Par exemple, un garbage collection de niveau 0 entraîne l’énumération uniquement des objets épinglés dans le tas de niveau 0. |
Nombre de blocs d'évier utilisés |
Affiche le nombre actuel de blocs de synchronisation dans utiliser. Un bloc de synchronisation est une structure de données basée sur des objets allouée au stockage des informations de synchronisation. Les blocs synchronisés contiennent des références faibles aux objets gérés et doivent être analysés par le garbage collector. Les blocs de synchronisation ne se limitent pas au stockage des informations de synchronisation ; ils peuvent également stocker des métadonnées COM Interop. Ce compteur indique des problèmes de performances liés à une utilisation excessive des primitives de synchronisation. |
# Total d'octets validés (nombre total d'octets validés) |
Afficher le garbage collection La quantité de mémoire virtuelle actuellement allouée par le serveur (en octets). La mémoire engagée est la mémoire physique de l'espace réservé dans le fichier d'échange du disque. |
# Total d'octets réservés (nombre total d'octets réservés) |
Afficher le garbage collection La quantité de mémoire virtuelle actuellement réservée par le serveur (en octets). La mémoire réservée est un espace mémoire virtuel réservé aux applications (mais qui n'a encore utilisé aucun disque ni aucune page de mémoire principale). |
% Time in GC (pourcentage de temps en GC) |
Affiche le temps depuis le dernier garbage collection Pourcentage de temps d'exécution consacré à la récupération de place après le cycle. Ce compteur indique généralement le travail effectué par le garbage collector pour le compte de l'application pour collecter et compacter la mémoire. Ce compteur n'est mis à jour qu'à la fin de chaque garbage collection. Ce compteur n'est pas une moyenne ; sa valeur reflète les observations les plus récentes. |
Octets alloués/seconde (nombre d'octets alloués par seconde) |
Afficher le nombre d'octets alloués sur le tas de garbage collection par seconde. Ce compteur est mis à jour à la fin de chaque garbage collection, et non à chaque allocation. Ce compteur n'est pas une moyenne dans le temps ; il affiche la différence entre les valeurs observées dans les deux échantillons les plus récents divisée par le temps écoulé entre les échantillons. |
Finalisation Survivants (le nombre d'objets restants une fois terminés) |
s'affiche car il est en attente d'achèvement. Le nombre d'objets conservés pour le garbage collection après la collecte. Si ces objets conservent des références à d'autres objets, ces objets sont conservés, mais ils ne sont pas comptés par ce compteur. Les compteurs Mémoire d'achèvement promue à partir du niveau 0 et Mémoire d'achèvement promue à partir du niveau 1 représentent toute la mémoire conservée en raison de l'achèvement. Ce compteur n'est pas un compteur cumulatif ; il est mis à jour à la fin de chaque garbage collection par un nombre d'objets qui ont survécu uniquement pendant cette collecte spécifique. Ce compteur indique qu'il peut y avoir une surcharge système excessive en raison de l'achèvement de l'application. |
Taille du tas Gen 0 |
Affiche le nombre maximum d'octets pouvant être alloués au niveau 0 ; il n'indique pas le nombre actuel d'octets alloués au niveau 0. Le garbage collection de niveau 0 se produit lorsque les allocations depuis la collecte la plus récente dépassent cette taille. La taille de niveau 0 est affinée par le garbage collector et peut changer pendant l'exécution de l'application. À la fin de la collecte de niveau 0, la taille du tas de niveau 0 est de 0 octet. Ce compteur indique la taille, en octets, de l'allocation qui appelle le garbage collection de niveau 0 suivant. Ce compteur est mis à jour à la fin du garbage collection (et non à chaque allocation). |
Gen 0 Octets promus/s (octets promus/s à partir du niveau 1) |
Affiche le nombre d'octets par seconde du niveau 0 au niveau 1. La mémoire est promue après avoir été conservée du garbage collection. Ce compteur est un indicateur des objets créés par seconde qui ont été conservés pendant une période de temps significative. Ce compteur affiche la différence entre les valeurs observées dans les deux derniers échantillons divisée par la durée de l'intervalle d'échantillonnage. |
Taille du tas Gen 1 (taille du tas Niveau 2) |
Afficher 1er Le courant nombre d'octets dans le niveau ; ce compteur n'affiche pas la taille maximale du niveau 1. Les objets ne sont pas alloués directement dans cette génération ; ces objets sont promus à partir des garbage collection de niveau 0 précédents. Ce compteur est mis à jour à la fin du garbage collection (pas à chaque allocation). |
Octets promus Gen 1/s (octets promus à partir du niveau 1/s) |
Affiche le nombre d'octets par seconde promus du niveau 1 au niveau 2. Les objets promus simplement parce qu'ils sont en attente d'achèvement ne sont pas inclus dans ce compteur. La mémoire est promue après avoir été conservée du garbage collection. Il n’y aura pas de promotion à partir du niveau 2 car il s’agit du niveau le plus ancien. Ce compteur est un indicateur des objets à très longue durée de vie créés par seconde. Ce compteur affiche la différence entre les valeurs observées dans les deux derniers échantillons divisée par la durée de l'intervalle d'échantillonnage. |
Taille du tas Gen 2 |
Afficher Gen 2 Le nombre actuel d'octets dans le niveau. Les objets ne sont pas alloués directement dans cette génération ; ces objets ont été promus du niveau 1 lors d'un garbage collection de niveau 1 précédent. Ce compteur est mis à jour à la fin du garbage collection (pas à chaque allocation). |
Large Object Taille du tas |
Afficher le tas d'objets volumineux Taille actuelle de,Moyenne octets. Le garbage collector traite les objets de plus de 20 Ko comme des objets volumineux et alloue les objets volumineux directement dans le tas spécial. Ils ne sont pas promus via ces niveaux. Ce compteur est mis à jour à la fin du garbage collection (pas à chaque allocation). |
Mémoire de finalisation promue à partir de la génération 0 |
Affiche le nombre d'octets de mémoire promu du niveau 0 au niveau 1 simplement en attendant d'être terminé. Ce compteur n'est pas un compteur cumulatif ; il affiche la valeur observée à la fin du dernier garbage collection. |
Mémoire de finalisation promue de la génération 1 |
Affiche le nombre d'octets de mémoire promus du niveau 1 au niveau 2 simplement en raison de l'attente de la fin. Ce compteur n'est pas un compteur cumulatif ; il affiche la valeur observée à la fin du dernier garbage collection. Si le dernier garbage collection était un garbage collection de niveau 0, ce compteur est réinitialisé à 0. |
Mémoire promue de la génération 0 |
Affiche le nombre d'octets de mémoire conservés après collecte des ordures et promu du niveau 0 au niveau 1. Sont exclus de ce compteur les objets qui ne sont soulevés qu'en attendant d'être terminés. Ce compteur n'est pas un compteur cumulatif ; il affiche la valeur observée à la fin du dernier garbage collection. |
Mémoire promue de la génération 1 |
Affiche le nombre d'octets de mémoire conservés après collecte des ordures et promu du niveau 1 au niveau 2. Sont exclus de ce compteur les objets qui ne sont soulevés qu'en attendant d'être terminés. Ce compteur n'est pas un compteur cumulatif ; il affiche la valeur observée à la fin du dernier garbage collection. Si le dernier garbage collection était un garbage collection de niveau 0, ce compteur est réinitialisé à 0. |
Ce tableau provient de MSDN
Ce qui précède est le contenu du principe du mécanisme de collecte des ordures .Net (2). veuillez faire attention à PHP Chinese Net (www.php.cn) !