Я оптимизировал производительность памяти в приложении Windows Mobile и столкнулся с некоторыми различиями в поведении между VirtualAlloc на Win32 и Windows CE .
Рассмотрим следующий тест:
// Allocate 64k of memory
BYTE *a = (BYTE*)VirtualAlloc(0, 65536,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
// Allocate a second contiguous 64k of memory
BYTE *b = (BYTE*)VirtualAlloc(a+65536, 65536,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
BYTE *c = a + 65528; // Set a pointer near the end of the first allocation
BOOL valid1 = !IsBadWritePtr(c, 8); // Expect TRUE
BOOL valid2 = !IsBadWritePtr(c+8, 4088); // Expect TRUE
BOOL valid3 = !IsBadWritePtr(c, 4096); // TRUE on Win32, FALSE on WinCE
Код «выделяет» 4096 данных, начиная с «c». На Win32 это работает. Я не могу найти в документации VirtualAlloc никаких упоминаний о том, является ли это законным или совпадением, но я нашел много примеров кода, который я нашел в Google и который ожидает такого поведения.
В Windows CE 5.0 / 5.2, если я использую блок памяти в «c», в 99% случаев проблем не возникает, однако на некоторых (не на всех) устройствах Windows Mobile 6 ReadFile & WriteFile завершится с ошибкой 87 (параметр неверен.). Я предполагаю, что ReadFile вызывает IsBadWritePtr или подобное и возвращает ложь из-за этого. Если я выполняю два ReadFile вызова, то все работает нормально. (Конечно, могут быть и другие вызовы API, которые также не будут работать.)
Я ищу способ расширить память, возвращаемую VirtualAlloc , чтобы я мог заставить работать выше. Резервирование большого объема памяти в Windows CE проблематично, поскольку каждый процесс получает только 32 МБ, а из-за загрузки других элементов невозможно зарезервировать большой объем памяти, не вызывая других проблем. (Можно зарезервировать больший объем памяти в общей области, но это также имеет другие проблемы.)
Есть ли способ получить VirtualAlloc для увеличения или объединения регионов без предварительного резервирования?
Я подозреваю, что это может быть проблематично, учитывая следующие примеры:
HANDLE hHeap1 = HeapCreate(0, 0, 0); // Heap defaults to 192k
BYTE * a1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +96 bytes from start of heap
BYTE * b1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of a1
BYTE * c1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of b1
BYTE * d1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +4528 bytes from end of c1
HANDLE hHeap2 = HeapCreate(0, 4*1024*1024, 4*1024*1024); // 4MB Heap
BYTE * a2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +96 bytes from start of heap
BYTE * b2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of a2
BYTE * c2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of b2
BYTE * d2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of c2