1

J'ai créé une application de test simple comme suit.Pourquoi ce code affiche-t-il une consommation de mémoire native plus élevée?

using System; 
using System.Collections.Generic; 
using System.Threading; 
using System.Threading.Tasks; 

namespace PerfMonTest 
{ 
    class Program 
    { 
     private static List<byte[]> byteArray = new List<byte[]>(); 
     static void Main(string[] args) 
     { 
      Console.WriteLine("start now"); 
      Console.ReadLine(); 
      Task t1 = Task.Factory.StartNew(() => { Program.ProcessData(); }); 


      Task.WaitAll(new Task[] { t1}); 
      Console.WriteLine("done ..."); 
      Console.ReadLine(); 
     } 

     private static byte[] GetData() 
     { 
      return new byte[1024 * 1024 * 50]; 
     } 

     public static void ProcessData() 
     { 
      for (int i = 0; i < 50000; i++) 
      { 
       byteArray.Add(GetData()); 
       Thread.Sleep(500); 
       Console.WriteLine("GC Memory consumed:" + Convert.ToString((GC.GetTotalMemory(false)/(1024 * 1024))) + " MB"); 
      } 
     } 
    } 
} 

Bien que cette application est en cours d'exécution, je suis aussi la capture des deux compteurs Private Bytes et # Bytes in all heaps. Son résultat ressemble à ceci.

enter image description here

Selon cette article, le graphique devrait ressembler suivant. enter image description here

Ma question est de savoir pourquoi les octets privés augmentent même si le nombre d'octets dans tous les tas augmente à peine. Ou mon code peut provoquer une fuite natif qui apparaît dans le compteur Private bytes?

Répondre

2

Le problème est que vous utilisez un test incroyablement artificiel, qui ne correspond pas aux scénarios du monde réel.

Vous allouez new byte[...] mais il n'est jamais hors de portée et par conséquent, il n'est pas collecté par le garbage collector. C'est pourquoi vous obtenez une ligne sans cesse croissante pour private bytes.

De même, byteArray est affecté sur le tas et n'est pas hors de portée. Il faut allouer plus d'espace à mesure qu'il grandit, mais il se développe en morceaux, ce qui explique pourquoi vous obtenez ces étapes dans le bytes in all heaps. Si vous supprimiez périodiquement des entrées de la liste, vous verriez que le private bytes fonctionnerait de la même manière que le graphique de l'article, bien que la liste elle-même (et donc le tas) ne serait jamais rétrécir en octets alloués.