¿Cómo comprobar usted mismo el código NodeJS en busca de pérdidas de memoria?
#ifdef _DEBUG
Inline void * __cdecl operator new (unsigned int size,
const char *file, int line )
{
};
Eliminación del operador __cdecl en línea (void *p)
{
};
#endif
De esta forma sobrecargamos los operadores new y delete. Envolvemos estos dos operadores sobrecargados con $ifdef y #endif para que estos dos operadores no aparezcan en la versión de lanzamiento. Si observa este código, verá que el nuevo operador toma tres argumentos, que son el tamaño de la memoria asignada, el nombre del archivo en el que aparece y el número de línea. Esto es necesario e importante para encontrar pérdidas de memoria. De lo contrario, llevará mucho tiempo saber dónde aparecen exactamente. Con este código, nuestro código que llama a new() todavía apunta a un nuevo operador que toma solo un argumento, en lugar de un operador que toma tres argumentos. Además, no queremos registrar que todas las declaraciones del nuevo operador contengan los parámetros __FILE__ y __LINE__. Lo que debemos hacer es hacer que todos los operadores nuevos que toman un argumento llamen automáticamente a operadores nuevos que toman tres argumentos. Esto requiere un poco de habilidad, como la siguiente definición de macro,
#ifdef _DEBUG
#define DEBUG_NEW new(__FILE__, __LINE__)
#Otherwise
#define DEBUG_NEW new
#endif
#Define new DEBUG_NEW
Ahora todos nuestros nuevos operadores que aceptan un parámetro se convierten en nuevos operador que acepta tres parámetros, y el precompilador inserta automáticamente __FILE__ y __LINE__. Luego, está el seguimiento real. Necesitamos agregar algunas rutinas a nuestras funciones sobrecargadas para que puedan asignar y liberar memoria. Para hacer esto, #ifdef _DEBUG
inline void * __cdecl operador nuevo (unsigned int size,
const char *file, int line)
{ p>
void * ptr = (void *)malloc(tamaño);
AddTrack((DWORD)ptr, tamaño, archivo, línea);
Return (ptr) ;
};
El operador __cdecl anulado en línea elimina (void *p)
{
eliminar pista( (DWORD)p) ;
Gratis(p);
};
#endif
Además, necesita una forma de sobrecargar el nuevo[ ] y eliminar [] operadores. Omitido aquí.
Finalmente, necesitamos proporcionar un conjunto de funciones AddTrack() y RemoveTrack(). Utilizo STL para mantener una tabla de unión que almacena registros de asignación de memoria.
Las dos funciones son las siguientes:
estructura typedef {
Dirección de palabra doble
Tamaño de palabra doble
;archivo char[64];
línea DWORD;
} ALLOC _ INFO
lista typedef & ltALLOC _ INFO * & gtAllocList
AllocList * allocList
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum)
{
ALLOC _ INFO * info
If (!allocList) {
allocList = nuevo(allocList);
}
INFO = nuevo(ALLOC _ INFO)
info->address=addr
strncpy(info->file,fname,63);
info->line= lnum<; /p>
Información->tamaño = asize
allocList->insert(allocList->begin(), info);
} ;
void RemoveTrack(doble dirección)
{
AllocList::Iterator I;
If (!allocList)
Regresar ;
for(I = allocList-& gt; comenzar(); I! = allocList-& gt; end(); i++)
{
if((* I)-& gt; dirección == dirección)
{
allocList-& gt; eliminar ((* I)); Break;
}
}
};
Ahora, antes de que nuestro programa salga, allocList almacena asignaciones de memoria que aún no han sido liberado. Para ver qué son y dónde están asignados, necesitamos imprimir los datos en allocList. Utilizo la ventana de salida en Visual C++ para lograr esto.
void DumpUnfreed()
{
AllocList::Iterator I;
Tamaño total de DWORD = 0;
char buf[1024];
if(!allocList)
return;
for(I = allocList->begin(); i! = allocList-> end(); i++) {
sprintf(buf, "%-50s: Línea %d, dirección %d %d no publicada",
(* I)->Archivo, (*I)->Línea, (*I)->Dirección, (*I)->Tamaño);
OutputDebugString (buf);
tamaño total+=(* I)-& gt; tamaño;
}
sprintf(buf, "-");
p>
OutputDebugString(buf);
sprintf(buf, "Cantidad total no publicada: %d bytes", Tamaño total);
OutputDebugString(buf);
};
Ahora tenemos un código reutilizable para monitorear y rastrear todas las pérdidas de memoria. Este código se puede agregar a todos los proyectos. Aunque no hará que su programa se vea mejor, al menos puede ayudarlo a verificar si hay errores y hacer que el programa sea más estable.