2010-11-01 6 views
5

Tengo una aplicación Visual Studio 2008 C++ para Windows Mobile 6.x donde estoy contando la cantidad de memoria virtual libre disponible para un proceso determinado. (Me di cuenta de que no está tomando la fragmentación en cuenta.) Mi código es básicamente lo siguiente:Explicar una línea de complementos de dos matemática contar memoria virtual libre

MEMORY_BASIC_INFORMATION mbi = { 0 }; 

/// total free memory available to the process 
DWORD free = 0; 

/// base memory address for the given process index (2-33). 
DWORD slot_base_addr = process_index * 0x02000000; 

/// look at each memory region for the process. 
for(DWORD offset = 0x10000; 
    offset < 0x02000000; 
    offset += mbi.RegionSize) 
{ 
    ::VirtualQuery((void*)(slot_base_addr + offset), 
        &mbi, 
        sizeof(MEMORY_BASIC_INFORMATION)); 

    if(mbi.State == MEM_FREE) 
    { 
     free += (mbi.RegionSize - ((~(DWORD)mbi.BaseAddress + 1) & 0xffff)) & 0xffff0000; 
    } 
} 
NKDbgPrintfW(L"%d bytes free\r\n", free); 

puedo confirmar con otras APIs que esto parece funcionar perfectamente. Mi pregunta es ¿qué está haciendo esta línea:

free += (mbi.RegionSize - ((~(DWORD)mbi.BaseAddress + 1) & 0xffff)) & 0xffff0000; 

¿Por qué es esto, no sólo:

free += mbi.RegionSize; 

me encontré con la antigua línea en un poste Usenet por empleado MSFT Ross Jordan.

Gracias, PaulH


Editar:

Por ejemplo. Para la ranura 2 del proceso, esta es una lista de cada bloque de memoria libre con la cantidad de memoria gratuita proporcionada por el algoritmo Ross Jordan (RS) y solo el RegionSize (RS).

Slot: 2. Range: 0x04000000 - 0x06000000 
    RS: 16,384 bytes RJ:   0 bytes diff: 16384 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS: 36,864 bytes RJ:   0 bytes diff: 36864 
    RS: 65,536 bytes RJ: 65,536 bytes diff: 0 
    RS: 53,248 bytes RJ:   0 bytes diff: 53248 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS: 7,671,808 bytes RJ: 7,667,712 bytes diff: 4096 
    RS: 1,921,024 bytes RJ: 1,900,544 bytes diff: 20480 
    RS: 7,491,584 bytes RJ: 7,471,104 bytes diff: 20480 
    RS: 3,252,224 bytes RJ: 3,211,264 bytes diff: 40960 
    RS: 262,144 bytes RJ: 262,144 bytes diff: 0 

RS: Total VM Free: 20,811,776 bytes. 
RJ: Total VM Free: 20,578,304 bytes. 

Edición 2:

Hans me llevó a la respuesta. Es solo una forma elegante de hacerlo, pero suponiendo que el tamaño de la asignación es de 64 KB.

SYSTEM_INFO si = { 0 }; 
::GetSystemInfo(&si); 

free += mbi.RegionSize - mbi.RegionSize % si.dwAllocationGranularity; 

Respuesta

2

La asignación de granularidad para VirtualAlloc es normalmente de 64 KB. Intenta hacer algo significativo si la AllocationBase no es un múltiplo de 64 KB. No creo que sea significativo en absoluto, sus máscaras de bits todavía suponen una granularidad de 64 KB y no utiliza SYSTEM_INFO.dwAllocationGranularity. Que cuenta con este comentario:

Este valor fue codificado como 64 KB de el pasado, pero el otro hardware arquitecturas puede requerir diferentes valores.

En el muy raro caso de que no sea 64KB, este código generará valores basura. Solo descárgalo, ve por RegionSize.

+0

Algo allí es importante. La memoria disponible para el 'proceso actual' dada por ese algoritmo coincide con lo que 'GlobalMemoryStatus()' dice que es. Si simplemente uso 'RegionSize', el resultado es consistentemente más pequeño en un par de docenas de KB. Como referencia, mi dwAllocationGranularity es de 64 KB. – PaulH

+0

Erm, ¿cómo es eso posible? La declaración * resta * del Tamaño de la Región. Solo puede hacerlo más pequeño, no más grande. Si te gusta GlobalMemoryStatus, tal vez deberías usar eso. –

+0

+1, Windows Mobile es bastante probable que sea uno de los "otros accesorios de hardware" –