Форум: "Основная";
Текущий архив: 2002.02.21;
Скачать: [xml.tar.bz2];
ВнизДинамические массивы Найти похожие ветки
← →
Basilio (2002-02-05 16:06) [0]проблема состоит в следующем:
Пусть есть два (или более) динамических массивов (ДМ) A и B, элементами
которых являются структуры (record), в которых присутствуют поля типа ДМ.
(тестировалось и для полей типа string)
Если поочередно увеличивать длину массивов A и B, при этом не забывая
инициализировать поля-массивы (иначе не интересно), то возникают какие-то
чудеса с памятью. Это очень заметно по файлу подкачки (если не фиксировать
его размер средствами Windows).
Чудеса состоят в следующем: при длине массивов (А,В) примерно 10000,
фактически используемая память должна быть примерно 10000*2*K+delta
Использованную память узнаём через GetHeapStatus.
Где K- длина структуры вместе с полями-ДМ (примерно одинакова для всех
структур в массивах A и B)
delta - какие-нибудь системные расходы, вроде размера кода и локальных
переменных.
Т.Е. использованная память составляет примерно 2 МБ. (если K порядка 50 и
delta порядка 100 КБ)
Однако размер файла подкачки зашкаливает за 500 МБ (при начальном размере
примерно 70 МБ)
Какие данные при этом возвращает GetHeapStatus, не понятно.
например, при длине массивов N=1000, значения следующие:
Total :5242880 // !!! 5МБ - терпимо
Allocated :101788
Free :4977308
А при N=4000, значения такие:
Total :116391936 // !!! 100 МБ
Allocated :101788
Free :4977308
При это Allocated принимает правдоподобные значения.
При этом данные сохраняют целостность, однако доступ к ним чрезвычайно
медленный. такое впечатление, что эти 2 МБ оказываются "размазанными" по
всему 500МБ файлу подкачки. Эдакая фрагментация памяти. Подскажите, как с
этим бороться.
uses SysUtils;
type MyRec=record
Arr:array of integer;
S:string;
end;
var A,B:array of MyRec;
i,N,j:integer;
HS:THeapStatus; // чтобы следить за памятью
begin
N:=5000;
SetLength(A,0);
for i:=1 to N do
begin
// A
SetLength(A,i);
SetLength(A[i-1].Arr,4);
for j:=0 to 3 do A[i-1].Arr[j]:=j*100;
A[i-1].S:="Str:"+IntToStr(i);
// B
SetLength(B,i);
SetLength(B[i-1].Arr,5);
for j:=0 to 3 do B[i-1].Arr[j]:=j*200;
B[i-1].S:="Str:"+IntToStr(i);
if i mod 1000 =0 then // каждые 1000 шагов вывести состояние памяти
begin
HS:=GetHeapStatus;
with HS do
begin
writeln("-----",i,"-----");
writeln("Total :", TotalAddrSpace);
writeln("Allocated :", TotalAllocated);
writeln("Free :", TotalFree);
end;
end;
end;
// печальный итог: фактическая загруженность памяти: O(N) байт,
// реальная память, использованная системой на поддержание жизнедеятельности
// процесса: около O(N^2)
// при этом неимоверно растет файл подкачки, и как следствие, падает
// производительность.
// Подскажите, как с этим бороться
end.
← →
Basilio (2002-02-05 18:12) [1]Пардон, данные по памяти опечатались..
-----1000-----
Total :5242880
Allocated :101788
Free :4977308
-----2000-----
Total :23068672
Allocated :209800
Free :22416944
-----3000-----
Total :62914560
Allocated :317804
Free :55108436
-----4000-----
Total :116391936
Allocated :425804
Free :87862088
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.02.21;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.004 c