Eventos de montón ETW nativos personalizadosCustom native ETW heap events

Visual Studio contiene diversas herramientas de diagnóstico y de generación de perfiles, incluido un generador de perfiles de memoria nativa.Visual Studio contains a variety of profiling and diagnostic tools, including a native memory profiler. Este generador de perfiles enlaza los eventos ETW del proveedor de montón y proporciona un análisis de la manera en que la memoria se asigna y se usa.This profiler hooks ETW events from the heap provider and provides analysis of how memory is being allocated and used. De forma predeterminada, esta herramienta solo puede analizar las asignaciones realizadas desde el montón de Windows estándar y no se mostrarán las asignaciones que se encuentran fuera de este montón nativo.By default, this tool can only analyze allocations made from the standard Windows heap, and any allocations outside this native heap would not be displayed.

Hay muchos casos en los que podría interesarle usar su propio montón personalizado y evitar la sobrecarga de asignación del montón estándar.There are many cases in which you may want to use your own custom heap and avoid the allocation overhead from the standard heap. Por ejemplo, puede usar VirtualAlloc para asignar una gran cantidad de memoria cuando se inicia la aplicación o el juego y, después, administrar sus propios bloques dentro de esa lista.For instance, you could use VirtualAlloc to allocate a large amount of memory at the start of the app or game, and then manage your own blocks within that list. En este escenario, la herramienta de generador de perfiles de memoria solo vería esa asignación inicial y no la administración personalizada realizada dentro del bloque de memoria.In this scenario, the memory profiler tool would only see that initial allocation, and not your custom management done inside the memory chunk. En cambio, mediante el uso del proveedor ETW de montón nativo personalizado, puede dejar que la herramienta conozca las asignaciones que realiza fuera del montón estándar.However, using the Custom Native Heap ETW Provider, you can let the tool know about any allocations you are making outside the standard heap.

Por ejemplo, en un proyecto similar al siguiente, donde MemoryPool es un montón personalizado, solo vería una única asignación en el montón de Windows:For example, in a project like the following where MemoryPool is a custom heap, you would only see a single allocation on the Windows heap:

class Foo
{
public:
    int x, y;
};

...

// MemoryPool is a custom managed heap, which allocates 8192 bytes 
// on the standard Windows Heap named "Windows NT"
MemoryPool<Foo, 8192> mPool;

// the "allocate" method requests memory from the pool created above
// and is cast to an object of type Foo, shown above
Foo* pFoo1 = (Foo*)mPool.allocate();
Foo* pFoo2 = (Foo*)mPool.allocate();
Foo* pFoo3 = (Foo*)mPool.allocate();

En una instantánea de la herramienta Uso de memoria sin el seguimiento del montón personalizado, solo se mostraría la asignación de 8192 bytes y ninguna de las asignaciones personalizadas realizadas por el grupo:A snapshot from the Memory Usage tool without custom heap tracking would show just the single 8192 byte allocation, and none of the custom allocations being made by the pool:

Asignación del montón de Windows

Mediante los pasos siguientes, podemos usar esta misma herramienta para realizar un seguimiento del uso de memoria en el montón personalizado.By performing the following steps, we can use this same tool to track memory usgae in our custom heap.

Cómo se usaHow to use

Esta biblioteca se puede usar fácilmente en C y C++.This library can be easily used in C and C++.

  1. Incluya el encabezado para el proveedor ETW de montón personalizado:Include the header for the custom heap ETW provider:

    #include <VSCustomNativeHeapEtwProvider.h>
    
  2. Agregue el elemento Decorator __declspec(allocator) a cualquier función del administrador de montones personalizados que devuelva un puntero a la memoria de montón recién asignada.Add the __declspec(allocator) decorator to any function in your custom heap manager that returns a pointer to newly allocated heap memory. Este elemento Decorator permite que la herramienta identifique correctamente el tipo de la memoria que se devuelve.This decorator allows the tool to correctly identify the type of the memory being returned. Por ejemplo:For example:

    __declspec(allocator) void *MyMalloc(size_t size);
    

    Nota

    Este elemento Decorator le indica al compilador que esta función es una llamada a un asignador.This decorator will tell the compiler that this function is a call to an allocator. Cada llamada a la función dará como resultado la dirección del sitio de llamada, el tamaño de la instrucción de llamada y el identificador de tipo del nuevo objeto en un nuevo símbolo S_HEAPALLOCSITE.Each call to the function will output the address of the callsite, the size of the call instruction, and the typeId of the new object to a new S_HEAPALLOCSITE symbol. Cuando se asigna una pila de llamadas, Windows emite un evento ETW con esta información.When a callstack is allocated, Windows will emit an ETW event with this information. La herramienta de generador de perfiles de memoria recorre la pila de llamadas en busca de una dirección de devolución que coincida con un símbolo S_HEAPALLOCSITE, y la información del identificador de tipo del símbolo se usa para mostrar el tipo de tiempo de ejecución de la asignación.The memory profiler tool walks the callstack looking for a return address matching an S_HEAPALLOCSITE symbol, and the typeId information in the symbol is used to display the runtime type of the allocation.

    En resumen, esto significa que una llamada similar a (B*)(A*)MyMalloc(sizeof(B)) se mostrará en la herramienta como si fuera de tipo B, no void o A.In short, this means a call that looks like (B*)(A*)MyMalloc(sizeof(B)) will show up in the tool as being of type B, not void or A.

  3. Para C++, cree el objeto VSHeapTracker::CHeapTracker y asígnele un nombre al montón, que se mostrará en la herramienta de generación de perfiles:For C++, create the VSHeapTracker::CHeapTracker object, providing a name for the heap, which will show up in the profiling tool:

    auto pHeapTracker = std::make_unique<VSHeapTracker::CHeapTracker>("MyCustomHeap");
    

    Si usa C, use la función OpenHeapTracker.If you are using C, use the OpenHeapTracker function instead. Esta función devuelve un identificador que usará cuando realice una llamada a otras funciones de seguimiento:This function will return a handle that you will use when calling other tracking functions:

    VSHeapTrackerHandle hHeapTracker = OpenHeapTracker("MyHeap");
    
  4. Cuando asigne memoria mediante la función personalizada, llame al método AllocateEvent (C++) o VSHeapTrackerAllocateEvent (C) y pase el puntero a la memoria y su tamaño para realizar un seguimiento de la asignación:When allocating memory using your custom function, call the AllocateEvent (C++) or VSHeapTrackerAllocateEvent (C) method, passing in the pointer to the memory and its size, to track the allocation:

    pHeapTracker->AllocateEvent(memPtr, size);
    

    oor

    VSHeapTrackerAllocateEvent(hHeapTracker, memPtr, size);
    

    Importante

    No olvide etiquetar la función de asignador personalizado con el elemento Decorator __declspec(allocator) descrito anteriormente.Don't forget to tag your custom allocator function with the __declspec(allocator) decorator described earlier.

  5. Cuando desasigne memoria mediante la función personalizada, llame a la función DeallocateEvent (C++) o VSHeapTracerDeallocateEvent (C) y pase el puntero a la memoria para realizar un seguimiento de la desasignación:When deallocating memory using your custom function, call the DeallocateEvent (C++) or VSHeapTracerDeallocateEvent (C) function, passing in the pointer to the memory, to track the deallocation:

    pHeapTracker->DeallocateEvent(memPtr);
    

    O bienor:

    VSHeapTrackerDeallocateEvent(hHeapTracker, memPtr);
    
  6. Cuando reasigne memoria mediante la función personalizada, llame al método ReallocateEvent (C++) o VSHeapReallocateEvent (C), pase un puntero a la memoria nueva y al tamaño de la asignación, y pase un puntero a la memoria antigua:When reallocating memory using your custom function, call the ReallocateEvent (C++) or VSHeapReallocateEvent (C) method, passing in a pointer to the new memory, the size of the allocation, and a pointer to the old memory:

    pHeapTracker->ReallocateEvent(memPtrNew, size, memPtrOld);
    

    O bienor:

    VSHeapTrackerReallocateEvent(hHeapTracker, memPtrNew, size, memPtrOld);
    
  7. Por último, para cerrar y limpiar el rastreador de montón personalizado en C++, use el destructor CHeapTracker, ya sea manualmente o a través de reglas de ámbito estándar, o la función CloseHeapTracker en C:Finally, to close and clean up the custom heap tracker in C++, use the CHeapTracker destructor, either manually or via standard scoping rules, or the CloseHeapTracker function in C:

    delete pHeapTracker;
    

    O bienor:

    CloseHeapTracker(hHeapTracker);
    

Realizar un seguimiento del uso de la memoriaTrack memory usage

Una vez realizadas estas llamadas, se puede realizar un seguimiento del uso del montón personalizado mediante la herramienta estándar Uso de memoria en Visual Studio.With these calls in place, your custom heap usage can now be tracked using the standard Memory Usage tool in Visual Studio. Para obtener más información sobre cómo usar esta herramienta, vea la documentación sobre el uso de memoria.For more information on how to use this tool, please see the Memory Usage documentation. Asegúrese de que ha habilitado la generación de perfiles de montón con instantáneas. En caso contrario, no verá el uso del montón personalizado.Ensure you have enabled heap profiling with snapshots, otherwise you will not see your custom heap usage displayed.

Habilitar la generación de perfiles de montón

Para ver el seguimiento del montón personalizado, use la lista desplegable Montón situada en la esquina superior derecha de la ventana Instantánea para cambiar la vista del Montón de NT a su propio montón, con el nombre que le ha asignado anteriormente.To view your custom heap tracking, use the Heap dropdown located at the upper-right corner of the Snapshot window to change the view from NT Heap to your own heap as named previously.

Selección del montón

Mediante el ejemplo de código anterior, en el que MemoryPool crea un objeto VSHeapTracker::CHeapTracker, y nuestro propio método allocate que llama al método AllocateEvent, ahora puede ver el resultado de esa asignación personalizada, que muestra tres instancias con un total de 24 bytes, todas de tipo Foo.Using the code example above, with MemoryPool creating a VSHeapTracker::CHeapTracker object, and our own allocate method now calling the AllocateEvent method, you can now see the result of that custom allocation, showing three instances totaling 24 bytes, all of type Foo.

El montón predeterminado Montón de NT tiene el mismo aspecto que antes, pero se le ha agregado el objeto CHeapTracker.The default NT Heap heap looks the same as earlier, with the addition of our CHeapTracker object.

Montón de NT con el rastreador

Al igual que en el montón de Windows estándar, también puede usar esta herramienta para comparar instantáneas y buscar fugas y daños en el montón personalizado. Esto se describe en la documentación principal sobre el uso de memoria.As with the standard Windows heap, you can also use this tool to compare snapshots and look for leaks and corruption in your custom heap, which is described in the main Memory Usage documentation.

Sugerencia

Visual Studio también contiene la herramienta Uso de memoria en el conjunto de herramientas Generación de perfiles de rendimiento, que se habilita en la opción de menú Depurar>Generador de perfiles de rendimiento o mediante la combinación de teclado Alt+F2.Visual Studio also contains a Memory Usage tool in the Performance Profiling toolset, which is enabled from the Debug>Performance Profiler menu option, or the Alt+F2 keyboard combination. Esta característica no incluye el seguimiento del montón y no mostrará el montón personalizado como se describe aquí.This feature does not include heap tracking and will not display your custom heap as described here. Esta funcionalidad solo está incluida en la ventana Herramientas de diagnóstico, que se puede habilitar en el menú Depurar>Windows>Mostrar herramientas de diagnóstico o mediante la combinación de teclado Ctrl+Alt+F2.Only the Diagnostic Tools window, which can be enabled with the Debug>Windows>Show Diagnostic Tools menu, or the Ctrl+Alt+F2 keyboard combination, contains this functionality.

Vea tambiénSee also

Herramientas de generación de perfilesProfiling tools
Uso de memoriaMemory Usage