Gerenciamento automático de memóriaAutomatic Memory Management

O gerenciamento automático de memória é um dos serviços que o Common Language Runtime fornece durante a Execução gerenciada.Automatic memory management is one of the services that the Common Language Runtime provides during Managed Execution. O coletor de lixo do Common Language Runtime gerencia a alocação e a liberação de memória para um aplicativo.The Common Language Runtime's garbage collector manages the allocation and release of memory for an application. Para desenvolvedores, isso significa que você não tem que escrever código para executar tarefas de gerenciamento de memória quando desenvolver aplicativos gerenciados.For developers, this means that you do not have to write code to perform memory management tasks when you develop managed applications. O gerenciamento automático de memória pode eliminar problemas comuns, como esquecer de liberar um objeto e causar um vazamento de memória ou tentar acessar a memória de um objeto que já tinha sido liberado.Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak, or attempting to access memory for an object that has already been freed. Esta seção descreve como o coletor de lixo aloca e libera memória.This section describes how the garbage collector allocates and releases memory.

Alocando memóriaAllocating Memory

Quando você inicializa um novo processo, o tempo de execução reserva uma região contígua de espaço de endereço para o processo.When you initialize a new process, the runtime reserves a contiguous region of address space for the process. Esse espaço de endereço reservado é chamado de heap gerenciado.This reserved address space is called the managed heap. O heap gerenciado mantém um ponteiro para o endereço no qual o próximo objeto do heap será alocado.The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Inicialmente, esse ponteiro é definido como o endereço básico do heap gerenciado.Initially, this pointer is set to the managed heap's base address. Todos os tipos de referência são alocados no heap gerenciado.All reference types are allocated on the managed heap. Quando um aplicativo cria o primeiro tipo de referência, a memória é alocada para o tipo no endereço base do heap gerenciado.When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. Quando o aplicativo cria o próximo objeto, o coletor de lixo aloca memória para ele no espaço de endereço logo depois do primeiro objeto.When the application creates the next object, the garbage collector allocates memory for it in the address space immediately following the first object. Desde que exista espaço de endereço disponível, o coletor de lixo continua alocando espaço para novos objetos dessa maneira.As long as address space is available, the garbage collector continues to allocate space for new objects in this manner.

A alocação memória com base no heap gerenciado é mais rápida do que a alocação de memória não gerenciada.Allocating memory from the managed heap is faster than unmanaged memory allocation. Como o tempo de execução aloca memória para um objeto adicionando um valor a um ponteiro, ele é quase tão rápido quanto a alocação de memória com base na pilha.Because the runtime allocates memory for an object by adding a value to a pointer, it is almost as fast as allocating memory from the stack. Além disso, como novos objetos que são alocados consecutivamente são armazenados contiguamente no heap gerenciado, um aplicativo pode acessar os objetos muito rapidamente.In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects very quickly.

Liberando memóriaReleasing Memory

O mecanismo de otimização do coletor de lixo determina o melhor momento para executar uma coleta com base nas alocações que estão sendo feitas.The garbage collector's optimizing engine determines the best time to perform a collection based on the allocations being made. Quando o coletor de lixo executa uma coleta, ele libera a memória dos objetos que não estão mais sendo usados pelo aplicativo.When the garbage collector performs a collection, it releases the memory for objects that are no longer being used by the application. Ele determina quais objetos não estão mais sendo usados examinando as raízes do aplicativo.It determines which objects are no longer being used by examining the application's roots. Cada aplicativo tem um conjunto de raízes.Every application has a set of roots. Cada raiz refere-se a um objeto no heap gerenciado ou é definida como nula.Each root either refers to an object on the managed heap or is set to null. As raízes de um aplicativo incluem campos estáticos, variáveis locais e parâmetros na pilha de um thread, além de registros de CPU.An application's roots include static fields, local variables and parameters on a thread's stack, and CPU registers. O coletor de lixo tem acesso à lista de raízes ativas mantidas pelo tempo de execução e pelo compilador JIT (Just-In-Time).The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the runtime maintain. Usando essa lista, ele examina as raízes de um aplicativo e, no processo, cria um gráfico que contém todos os objetos que possam ser alcançados nas raízes.Using this list, it examines an application's roots, and in the process creates a graph that contains all the objects that are reachable from the roots.

Objetos que não estão no gráfico são inacessíveis a partir das raízes do aplicativo.Objects that are not in the graph are unreachable from the application's roots. O coletor de lixo considera lixo os objetos inacessíveis e liberará a memória alocada para eles.The garbage collector considers unreachable objects garbage and will release the memory allocated for them. Durante uma coleta, o coletor de lixo examina o heap gerenciado, procurando os blocos de espaço de endereço ocupados por objetos inacessíveis.During a collection, the garbage collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. Na medida em que descobre cada objeto inacessível, ele usa uma função de cópia de memória para compactar os objetos acessíveis na memória, liberando os blocos de espaços de endereço alocados para objetos inacessíveis.As it discovers each unreachable object, it uses a memory-copying function to compact the reachable objects in memory, freeing up the blocks of address spaces allocated to unreachable objects. Uma vez que a memória dos objetos acessíveis tenha sido compactada, o coletor de lixo faz as correções necessárias no ponteiro de forma que as raízes do aplicativo apontem para os objetos em seus novos locais.Once the memory for the reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the application's roots point to the objects in their new locations. Ele também posiciona o ponteiro do heap gerenciado após o último objeto acessível.It also positions the managed heap's pointer after the last reachable object. Observe que memória é compactada somente se uma coleta descobre um número significativo de objetos inacessíveis.Note that memory is compacted only if a collection discovers a significant number of unreachable objects. Se todos os objetos no heap gerenciado sobrevivem a uma coleta, não há necessidade de compactação de memória.If all the objects in the managed heap survive a collection, then there is no need for memory compaction.

Para melhorar o desempenho, o tempo de execução aloca memória para objetos grandes em um heap separado.To improve performance, the runtime allocates memory for large objects in a separate heap. O coletor de lixo automaticamente libera a memória para objetos grandes.The garbage collector automatically releases the memory for large objects. No entanto, para evitar mover objetos grandes na memória, essa memória não é compactada.However, to avoid moving large objects in memory, this memory is not compacted.

Gerações e desempenhoGenerations and Performance

Para otimizar o desempenho do coletor de lixo, o heap gerenciado é dividido em três gerações: 0, 1 e 2.To optimize the performance of the garbage collector, the managed heap is divided into three generations: 0, 1, and 2. O algoritmo da coleta de lixo do tempo de execução é baseado em várias generalizações que a indústria de software de computador descobriu serem verdadeiras experimentando os esquemas da coleta de lixo.The runtime's garbage collection algorithm is based on several generalizations that the computer software industry has discovered to be true by experimenting with garbage collection schemes. Primeiro, é mais rápido compactar a memória para uma parte do heap gerenciado do que para o heap gerenciado inteiro.First, it is faster to compact the memory for a portion of the managed heap than for the entire managed heap. Em segundo lugar, objetos mais recentes terão vidas úteis menores e objetos mais antigos objetos terão vidas úteis maiores.Secondly, newer objects will have shorter lifetimes and older objects will have longer lifetimes. Finalmente, objetos mais recentes tendem a se relacionar e serem acessados pelo aplicativo aproximadamente ao mesmo tempo.Lastly, newer objects tend to be related to each other and accessed by the application around the same time.

O coletor de lixo do tempo de execução armazena novos objetos na geração 0.The runtime's garbage collector stores new objects in generation 0. Os objetos criados no início no tempo de vida do aplicativo que sobrevivem a coleções são promovidos e armazenados nas gerações 1 e 2.Objects created early in the application's lifetime that survive collections are promoted and stored in generations 1 and 2. O processo de promoção do objeto será descrito mais adiante neste tópico.The process of object promotion is described later in this topic. Como é mais rápido compactar uma parte do heap gerenciado do que o heap inteiro, esse esquema permite que o coletor de lixo libere a memória em uma geração específica em vez liberar a memória para toda a memória gerenciada a cada vez que ele executa uma coleta.Because it is faster to compact a portion of the managed heap than the entire heap, this scheme allows the garbage collector to release the memory in a specific generation rather than release the memory for the entire managed heap each time it performs a collection.

Na verdade, o coletor de lixo executa uma coleta quando a geração 0 está cheia.In reality, the garbage collector performs a collection when generation 0 is full. Se um aplicativo tentar criar um novo objeto quando a geração 0 está cheia, o coletor de lixo descobre que não existe nenhum espaço de endereço restante na geração 0 para alocar para o objeto.If an application attempts to create a new object when generation 0 is full, the garbage collector discovers that there is no address space remaining in generation 0 to allocate for the object. O coletor de lixo executa uma coleta em uma tentativa de liberar espaço de endereço na geração 0 para o objeto.The garbage collector performs a collection in an attempt to free address space in generation 0 for the object. O coletor de lixo inicia examinando os objetos na geração 0 em vez de todos os objetos no heap gerenciado.The garbage collector starts by examining the objects in generation 0 rather than all objects in the managed heap. Isso é a abordagem mais eficiente, porque novos objetos costumam ter tempos de vida curtos e é esperado que muitos dos objetos na geração 0 não estejam mais em uso pelo aplicativo quando uma coleta é executada.This is the most efficient approach, because new objects tend to have short lifetimes, and it is expected that many of the objects in generation 0 will no longer be in use by the application when a collection is performed. Além disso, uma única coleta de geração 0 normalmente recupera memória suficiente para permitir ao aplicativo continuar criando novos objetos.In addition, a collection of generation 0 alone often reclaims enough memory to allow the application to continue creating new objects.

Após o coletor de lixo executar uma coleta de geração 0, ele compacta a memória para os objetos acessíveis conforme explicado anteriormente neste tópico em Liberando memória.After the garbage collector performs a collection of generation 0, it compacts the memory for the reachable objects as explained in Releasing Memory earlier in this topic. Assim, o coletor de lixo promove esses objetos e considera isso parte da geração 1 do heap gerenciado.The garbage collector then promotes these objects and considers this portion of the managed heap generation 1. Como os objetos que sobrevivem a coleções tendem a ter tempos de vida mais longos, faz sentido promovê-los a uma geração mais alta.Because objects that survive collections tend to have longer lifetimes, it makes sense to promote them to a higher generation. Como resultado, o coletor de lixo não tem que reexaminar os objetos em gerações 1 e 2 sempre que executa uma coleta de geração 0.As a result, the garbage collector does not have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0.

Depois que o coletor de lixo executa sua primeira coleta de geração 0 e promove os objetos atingíveis para a geração 1, ele considera o restante do heap gerenciado a geração 0.After the garbage collector performs its first collection of generation 0 and promotes the reachable objects to generation 1, it considers the remainder of the managed heap generation 0. Ele continua alocando a memória para novos objetos na geração 0 até que a geração 0 esteja completa e seja necessário executar outra coleta.It continues to allocate memory for new objects in generation 0 until generation 0 is full and it is necessary to perform another collection. Nesse ponto, o mecanismo de otimização do coletor de lixo determina se é necessário examinar os objetos em gerações mais antigas.At this point, the garbage collector's optimizing engine determines whether it is necessary to examine the objects in older generations. Por exemplo, se uma coleta de geração 0 não recupera memória suficiente para que o aplicativo conclua com êxito a sua tentativa de criar um novo objeto, o coletor de lixo pode executar uma coleta de geração 1 e, então, de geração 2.For example, if a collection of generation 0 does not reclaim enough memory for the application to successfully complete its attempt to create a new object, the garbage collector can perform a collection of generation 1, then generation 2. Se isso não recuperar memória suficiente, o coletor de lixo poderá executar uma coleta de gerações 2, 1 e 0.If this does not reclaim enough memory, the garbage collector can perform a collection of generations 2, 1, and 0. Depois de cada coleta, o coletor de lixo compactará os objetos atingíveis na geração 0 e os promoverá para a geração 1.After each collection, the garbage collector compacts the reachable objects in generation 0 and promotes them to generation 1. Os objetos na geração 1 que sobrevivem a coleções são promovidos para a geração 2.Objects in generation 1 that survive collections are promoted to generation 2. Como o coletor de lixo só dá suporte a três gerações, os objetos na geração 2 que sobrevivem a uma coleta permanecem na geração 2 até serem considerados inacessíveis em uma coleta futura.Because the garbage collector supports only three generations, objects in generation 2 that survive a collection remain in generation 2 until they are determined to be unreachable in a future collection.

Liberando memória para recursos não gerenciadosReleasing Memory for Unmanaged Resources

Para a maioria dos objetos que seu aplicativo cria, você pode confiar no coletor de lixo para executar automaticamente as tarefas de gerenciamento de memória necessárias.For the majority of the objects that your application creates, you can rely on the garbage collector to automatically perform the necessary memory management tasks. Entretanto, recursos não gerenciados requerem limpeza explícita.However, unmanaged resources require explicit cleanup. O tipo mais comum de recursos não gerenciados é um objeto que encapsula um recurso do sistema operacional, como um identificador de arquivo, um identificador de janela ou uma conexão de rede.The most common type of unmanaged resource is an object that wraps an operating system resource, such as a file handle, window handle, or network connection. Embora o coletor de lixo seja capaz de acompanhar o tempo de vida de um objeto gerenciado que encapsule um recurso não gerenciado, ele não tem conhecimento específico sobre como limpar o recurso.Although the garbage collector is able to track the lifetime of a managed object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. Quando você cria um objeto que encapsula um recurso não gerenciado, é recomendável fornecer o código necessário para limpar o recurso não gerenciado em um método público Dispose.When you create an object that encapsulates an unmanaged resource, it is recommended that you provide the necessary code to clean up the unmanaged resource in a public Dispose method. Ao fornecer um método Dispose, você permite que usuários do seu objeto liberem, explicitamente, sua memória quando terminarem com o objeto.By providing a Dispose method, you enable users of your object to explicitly free its memory when they are finished with the object. Quando usa um objeto que encapsula um recurso não gerenciado, você deve estar ciente de Dispose e chamá-lo conforme necessário.When you use an object that encapsulates an unmanaged resource, you should be aware of Dispose and call it as necessary. Para obter mais informações sobre a limpeza de recursos não gerenciados e um exemplo de um padrão de design para implementar Dispose, consulte Coleta de lixo.For more information about cleaning up unmanaged resources and an example of a design pattern for implementing Dispose, see Garbage Collection.

Consulte tambémSee also