Interpretación de un volcado de objetos
Actualización: noviembre 2007
Este tema es aplicable a:
Edición |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Express |
Sólo para código nativo |
|||
Standard |
Sólo para código nativo |
|||
Pro y Team |
Sólo para código nativo |
Leyenda de la tabla:
Se aplica |
|
No procede |
|
Comando o comandos ocultos de manera predeterminada. |
Examine el siguiente volcado de objetos con mayor detalle:
{5} strcore.cpp(80) : non-object block at $00A7521A, 9 bytes long
{4} strcore.cpp(80) : non-object block at $00A751F8, 5 bytes long
{3} strcore.cpp(80) : non-object block at $00A751D6, 6 bytes long
{2} a CPerson at $51A4
Last Name: Smith
First Name: Alan
Phone #: 581-0215
{1} strcore.cpp(80) : non-object block at $00A7516E, 25 bytes long
El programa que generó este volcado sólo tenía dos asignaciones de memoria explícitas: una en la pila y otra en el montón:
// Do your memory allocations and deallocations.
CString s("This is a frame variable");
// The next object is a heap object.
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
El constructor CPerson recibe tres argumentos que son punteros a char y que se utilizan para inicializar variables miembro de CString. En el volcado de memoria, se puede ver el objeto CPerson junto con tres bloques que no corresponden a objetos (3, 4 y 5). Éstos contienen los caracteres para las variables miembro de CStringy no se eliminarán cuando se llame al destructor del objeto CPerson.
El bloque número 2 es el mismo objeto CPerson. $51A4 representa la dirección del bloque y va seguida por el contenido del objeto, volcado por CPerson::Dump al ser llamado por DumpAllObjectsSince.
El bloque número 1 se encuentra asociado con la variable CString del marco de trabajo, como se puede ver por su número de secuencia y tamaño, que coincide con el número de caracteres de la variable CString del marco. Las variables asignadas en el marco de trabajo se desasignan automáticamente cuando el marco se sale del ámbito.
Variables de marco
En general, no debería preocuparse de los objetos del montón asociados con variables de marco, ya que se desasignan automáticamente cuando las variables se salen de su ámbito. Para conseguir claridad y orden en los volcados de memoria, las llamadas a Checkpoint se deberían colocar de modo que se encuentren fuera del ámbito de las variables de marco. Por ejemplo, coloque el código de asignación anterior entre llaves de ámbito, como se muestra a continuación:
oldMemState.Checkpoint();
{
// Do your memory allocations and deallocations ...
CString s("This is a frame variable");
// The next object is a heap object.
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
}
newMemState.Checkpoint();
Con las llaves de ámbito, el volcado de memoria quedaría así:
Dumping objects ->
{5} strcore.cpp(80) : non-object block at $00A7521A, 9 bytes long
{4} strcore.cpp(80) : non-object block at $00A751F8, 5 bytes long
{3} strcore.cpp(80) : non-object block at $00A751D6, 6 bytes long
{2} a CPerson at $51A4
Last Name: Smith
First Name: Alan
Phone #: 581-0215
Asignaciones de elementos que no son objetos
Observe que algunas asignaciones corresponden a objetos (como CPerson) y otras a elementos que no son objetos. Las "asignaciones de elementos que no son objetos" son asignaciones de objetos no derivados de CObject o asignaciones de tipos C primitivos como char, int o long. Si la clase derivada de CObject asigna espacio adicional, como para los búferes internos, esos objetos mostrarán asignaciones de objetos y de elementos que no son objetos.
Evitar pérdidas de memoria
Observe en el código anterior que el bloque de memoria asociado a la variable de marco CString se desasignó automáticamente y no aparece como pérdida de memoria. La desasignación automática asociada a las reglas de ámbito se ocupa de la mayoría de las pérdidas de memoria relacionadas con variables de marco.
Sin embargo, para objetos asignados en el montón, se debe eliminar explícitamente cada objeto para evitar una pérdida de memoria. Para evitar la última pérdida de memoria del ejemplo anterior, elimine el objeto CPerson asignado en el montón, como se indica a continuación:
{
// Do your memory allocations and deallocations.
CString s("This is a frame variable");
// The next object is a heap object.
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
delete p;
}