Как (временно) освободить память от VirtualAlloc?
Когда используешь VirtualAlloc
Я могу (ab) использовать следующее свойство для упрощения управления памятью.
Фактические физические страницы не распределяются, если / пока виртуальный адрес фактически не доступен.
Я запускаю следующий код для выделения блока.
type
PArrayMem = ^TArrayMem; //pointer
TArrayMem = packed record //as per documentation
RefCount: Integer;
Length: NativeInt;
Elements: Integer;
end;
var
a: array of integer; //dynamic array, structure see above
procedure TForm38.Button1Click(Sender: TObject);
const
AllocSize = 1024 * 1024 * 1024; //1 GB
var
ArrayMem: PArrayMem;
begin
//SetLength(a, 1024*1024*1024); //1G x 8*16
ArrayMem:= VirtualAlloc(nil, AllocSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
ArrayMem.RefCount:= 1;
ArrayMem.Length:= AllocSize div SizeOf(Integer);
a:= @ArrayMem.Elements; //a:= AddressOf(elements)
a[1]:= 10; //testing, works
a[0]:= 4;
a[500000]:= 56; //Works, autocommits, only adds a few k to the used memory
button1.Caption:= IntToStr(a[500000]); //displays '56'
end;
Все это прекрасно работает. Если моя структура увеличивается до 1.000.000 элементов, все работает.
Однако предположим, что впоследствии моя структура сократилась до 1.000 элементов.
Как освободить ОЗУ, чтобы оно автоматически автоматически фиксировалось при необходимости?
ПРЕДУПРЕЖДЕНИЕ
Дэвид предупредил, что выделение больших (огромных) непрерывных страниц памяти сопряжено с большими затратами.
Поэтому может быть более выгодно разделить массив на более мелкие блоки и абстрагировать внутренние компоненты с помощью класса / записи.
1 ответ
Вы можете удалить страницы, используя VirtualFree
прохождение MEM_DECOMMIT
флаг. Затем вы можете зафиксировать снова, используя VirtualAlloc
,
Или вы можете использовать DiscardVirtualMemory
функция введена в Windows 8.1.
Используйте эту функцию для удаления содержимого памяти, которое больше не требуется, при сохранении самой области памяти. Сброс памяти может вернуть физическую оперативную память системе. Когда приложение снова обращается к области памяти, резервное ОЗУ восстанавливается, и содержимое памяти не определено.
Вы можете найти что-то полезное в комментариях к этому связанному вопросу: Новые API-интерфейсы Windows 8.1 для управления виртуальной памятью: `DiscardVirtualMemory()` vs `VirtualAlloc()` и `MEM_RESET` и`MEM_RESET_UNDO`