Воскресенье, 05.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Как часто ви на этот сайт заходите?
Всего ответов: 159
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Разные » Обзор Delphi

Секреты Delphi. Менеджер памяти

Я думаю, ни для кого не секрет, что некоторый запас свободной оперативной памяти для работы приложений влияет на производительность. Оптимизировать процесс распределения памяти между программами можно установкой специальных сервисов, которые периодически сбрасывают часть данных в своп-файл. Особенно это актуально на компьютерах с небольшим объемом оперативной памяти.

В процессе решения этой проблемы я попытался создать модуль освобождения оперативной памяти, который вызывался бы с некоторой периодичностью или перед выполнением длительных, ресурсоемких операций. Отсутствие информации по работе стандартного менеджера привело к следующему выводу: нужно попытаться выделить достаточно большой участок памяти под какой-нибудь объект, а затем освободить его. При этом менеджер памяти Windows сбрасывает часть данных в своп.
Пример функции, реализующей данный алгоритм:

function BS_FreeMem(const aBuf Size: Integer):boolean;
var
tmpBuffer: PChar;
begin
result:=true;
try
//Выделяем буфер заданного размера
GetMem(tmpBuffer, aBufSize);
try
//Заполняем буфер нулями для имитации его использования
FillChar(tmpBuffer^, aBufSize, 0); 
finally
FreeMem(tmpBuffer);
end;
except
result:=false;
end;
end;

На машинах класса Windows NT можно попробовать воспользоваться API-функцией SetProcessWorkingSetSize. 
Вызов данной функции со значениями параметров dwMinimumWorkingSetSize и dwMaximumWorkingSetSize, равными $FFFFFFFF, вызывает сброс страниц памяти, занятых процессом, в своп-файл. Например:

SetProcessWorkingSetSize (GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);

Вызывать созданную фунцию можно по таймеру, например:

procedure TfrmMain.Digital ClockMinute (Sender: TObject; DDGTime: TDateTime);
var
MemStat:TMemoryStatus;
fMemPercent:Extended;
bufSize:Variant;
oldHint:String;
oldCursor:TCursor;
begin
//Глобальная переменная, определяющая активность функции
if gInternalMemManager then
begin
MemStat.dwLength := SizeOf (TMemory Status);
GlobalMemoryStatus(Mem Stat);
fMemPercent:=(MemStat.dw TotalPhys-MemStat.dwAvailPhys);
fMemPercent:=fMemPercent* 100/MemStat. dwTotalPhys;
//Вызываем функцию, при загрузке памяти более 90%
if fMemPercent > 90 then
try
oldHint:=Application. Hint;
oldCursor:=Screen. Cursor;
Screen.Cursor:=crHour Glass;
Application.Hint:='Освобождение оперативной памяти..';
//вычисляем размер выделяемого буфера
bufSize:=(MemStat.dwTo-talPhys-MemStat.dwAvailPhys)/2;
BS_FreeMem(Integer (buf Size));
finally
Application.Hint:=oldHint;
Screen.Cursor:=oldCursor;
end;
end; 
end;

Следует заметить, что на 100% проблема не решается, так как на освобождение памяти требуется некоторое время, и вызов функции освобождения памяти может произойти в неподходящий момент — например, когда пользователь вводит данные и не смотрит на экран. Буду признателен за возможные идеи решения поставленной задачи.

Автор: Сергей Бердачук

Получить ссылку на материал

Категория: Обзор Delphi | Добавил: Барон (20.12.2011)
Просмотров: 1098 | Теги: память | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
Delphi.NET [3]
Kylix Delphi for Linux [9]
Советы Дельферу [6]
Хитрости в Delphi [2]
Обзор Delphi [45]
Инсталлятор [11]
Пользовательский интерфейс [18]
Примеры Delphi [93]
Функции и процедуры [15]
Разные [31]
Королевство Delphi © 2010-2024
Яндекс цитирования