Como obter memória não utilizada de volta da pilha de objetos grandes LOH de vários aplicativos gerenciados?

Enquanto conversava com um colega sobre um determinado grupo de aplicativos usando quase 1,5G de memória na inicialização ... ele me indicou um link muito bomDepuração de produção .NET

A parte que me intrigou é ...

Por exemplo, se você alocar 1 MB de memória em um único bloco, o heap de objeto grande se expandirá para 1 MB de tamanho. Quando você libera esse objeto, o heap de objeto grande não anula a memória virtual, portanto, o heap permanece no tamanho de 1 MB. Se você alocar outro bloco de 500 KB posteriormente, o novo bloco será alocado dentro do bloco de memória de 1 MB pertencente ao heap de objeto grande. Durante o tempo de vida do processo, o heap de objeto grande sempre aumenta para manter todas as grandes alocações de bloco atualmente referenciadas, mas nunca diminui quando os objetos são liberados, mesmo que ocorra uma coleta de lixo. A Figura 2.4 na próxima página mostra um exemplo de um grande heap de objetos.

Agora, digamos que temos um aplicativo fictício que cria uma enxurrada de objetos grandes (> 85KB), de modo que o grande heap de objeto cresce, digamos, para 200 Meg. Agora vamos dizer que temos 10 dessas instâncias de aplicativos em execução ... para que 2000 Megs sejam alocadas. Agora esta memória nunca é devolvida ao SO até que o processo seja encerrado ... (é o que eu entendi)

Há alguma lacuna no meu entendimento? Como podemos recuperar a memória não utilizada nos vários LOHeaps; nós não criamos a tempestade perfeita de OutOfMemoryExceptions?

Atualizar: A partir da resposta de Marc, eu queria esclarecer que os objetos LOH não são referenciados - os objetos grandes são use-n-throw - no entanto, o heap não encolhe, embora o heap esteja relativamente vazio após o surto inicial.

Atualização 2: Apenas incluindo um trecho de código (exagerado, mas entendi o ponto). Eu vejo um OutOfMemoryException quando a memória Virtual atinge a marca 1.5G na minha máquina (1.7G em outra).Publicação do blog de Eric L., 'memória de processo pode ser visualizada como um arquivo massivo no disco ..' - este resultado é, portanto, inesperado. As máquinas nesta instância tinham GB de espaço livre no disco rígido. O arquivo de sistema operacional PageFile.sys (ou configurações relacionadas) impõe alguma restrição?

<code>        static float _megaBytes;
        static readonly int BYTES_IN_MB = 1024*1024;

        static void BigBite()
        {
           try
           {
              var list = new List<byte[]>();
              int i = 1;

              for (int x = 0; x < 1500; x++)
              {
                 var memory = new byte[BYTES_IN_MB + i];
                 _megaBytes += memory.Length / BYTES_IN_MB;
                 list.Add(memory);
                 Console.WriteLine("Allocation #{0} : {1}MB now", i++, _megaBytes);
              }
           }
           catch (Exception e)
           {  Console.WriteLine("Boom! {0}", e); // I put a breakpoint here to check the console
              throw;
           }
        }
       static void Main(string[] args)
        {
            BigBite();
            Console.WriteLine("Check VM now!"); Console.ReadLine();
            _megaBytes = 0;

            ThreadPool.QueueUserWorkItem(delegate { BigBite(); });
            ThreadPool.QueueUserWorkItem(delegate { BigBite(); });
            Console.ReadLine();   // will blow before it reaches here
        }
</code>

questionAnswers(3)

yourAnswerToTheQuestion