Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
ВнизВопрос по памяти при работе с дтнамическими массивами Найти похожие ветки
← →
den777 (2004-02-02 18:41) [0]Вопрос по выделению и освобождению памяти при работе с динамическими массивами.
Trec = record
s:string;
i:integer;
ar:array of string;
ar1:array of TStrInt;
end;
var
ar:array of Trec;
s:string;
procedure procedure1;
var
i,j:integer;
begin
setlength(ar,0);
s:="012345678901234567890123456789012345678901234567890";
for i:=0 to ar1 do
begin
setlength(ar,length(ar)+1);
ar[i].s:=s;
end;
end;
procedure procedure2;
var
i,j:integer;
begin
setlength(ar,0);
for i:=0 to ar1 do
begin
setlength(ar,length(ar)+1);
ar[i].s:="012345678901234567890123456789012345678901234567890";
end;
end;
procedure procedure3;
var
i,j:integer;
begin
setlength(ar,0);
s:="012345678901234567890123456789012345678901234567890";
for i:=0 to ar1 do
begin
setlength(ar,length(ar)+1);
ar[i].s:="012345678901234567890123456789012345678901234567890";
setlength(ar[i].ar,10);
for j:=low(ar[i].ar) to high(ar[i].ar) do
begin
ar[i].ar[j]:=s;
end;
setlength(ar[i].ar1,10);
for j:=low(ar[i].ar1) to high(ar[i].ar1) do
begin
ar[i].ar1[j].s:=s;
ar[i].ar1[j].i:=2;
end;
end;
end;
1.Почему при работе procedure1 выделяется оперативной памяти в несколько раз меньше
чем, при работе procedure2.
2.Как при ar1=10 000 000 и длине s в 1000 символов procedure1 нормально
отрабатывает, занимая при этом в WIN2000 не более 80 Мб оперативки,
хотя тупое умножение ar1 на длину s даст 10Гб.
3.При отработке procedure3, где заполняются вложенные динамические массивы и последующем
setlength(ar,0) вся памтять вновь освобождается. При тестировании под memprof программы
работающей по сокетам и написанной под D5, memprof постоянно указывал при подобных
операциях на неосвобожденную память.Приходилось делать что-то типа
for i:=0 to setlength(ar) do
begin
ar[i].s:="";
.... //для всех динамически распределенных переменных что-то похожее
end;
и только потом давать setlength(ar,0)
После этого memprof переставал ругаться.
Как все-таки правильно, где и какая логика во всех вышеприведенных примерах.
Если есть статья по данной теме, киньте ссылочку.
← →
MBo (2004-02-02 18:46) [1]Собственно говоря, во всех примерах логики практически нет.
Увеличивать на каждом шаге длину массива на 1 вредно.
Обрати внимание на List-объекты (TList, TStringList)
>занимая при этом в WIN2000 не более 80 Мб оперативки,
хотя тупое умножение ar1 на длину s даст 10Гб.
физически строка - всего одна, в других элементах массива просто ссылка на нее же.
← →
Тимохов (2004-02-02 18:51) [2]Нет времени разбираться во всем коде, но по поводу
> 1.Почему при работе procedure1 выделяется оперативной памяти
> в несколько раз меньше
> чем, при работе procedure2.
могу сказать. При копировании строк копируется указатель на строку с одновременным увеличением счетчика ссылок.
В дальнейшем, если в строке сделать изменения, то для для такой строки создаться особая копия, где и будут делаться изменения.
В процедуре 1 у тебя копируется ссылка на константу, в процедуре 2, каждый раз создается новая константа в памяти.
← →
den777 (2004-02-02 19:01) [3]
> Увеличивать на каждом шаге длину массива на 1 вредно.
Знаем, проходили. Просили ответ, а не новые вопросы.
> физически строка - всего одна, в других элементах массива
> просто ссылка на нее же.
Не просто ссылка, а есть наверняка какой-то определенный механизм работы Delphi с памятью в таких случаях. Потому что при последующем ar[2].s:="fgdf" в ar[0].s,ar[1].s,ar[3].s и т.д. ничего не меняется, если была бы просто ссылка и ничего более, то изменилось бы во всех элементах сразу
> Обрати внимание на List-объекты (TList, TStringList)
Вопрос был не как лучше реализовать какую-то конкретную ситуацию, а помочь прояснить механизм работы представленных кодов, пусть и просто теоритических.
← →
Тимохов (2004-02-02 19:04) [4]
> 2.Как при ar1=10 000 000 и длине s в 1000 символов procedure1
> нормально
> отрабатывает, занимая при этом в WIN2000 не более 80 Мб
> оперативки,
> хотя тупое умножение ar1 на длину s даст 10Гб.
С этим ясно, см. мой предыдущий ответ.
Если ты потом модифицируешь каждую строку s в каждой записи(например, добавишь символ), то получишь свои 10 гб.
← →
den777 (2004-02-02 19:06) [5]
> В дальнейшем, если в строке сделать изменения, то для для
> такой строки создаться особая копия, где и будут делаться
> изменения.
Что-то подобное я и представлял. Хотелось-бы прочитать какую-нибудь статью на данную тему
← →
Тимохов (2004-02-02 19:08) [6]
> Что-то подобное я и представлял. Хотелось-бы прочитать какую-нибудь
> статью на данную тему
Всем вам статью подавай!
Почитай штатный хелп.
Раздел object pascal reference\memory managment.
Там все, обсуждаемое здесь, есть.
← →
Palladin (2004-02-02 19:11) [7]
> den777 (02.02.04 19:06) [5]
Интересно и что в этой статье должно быть написано? Ваши требования к ней?
← →
den777 (2004-02-02 19:12) [8]
> Раздел object pascal reference\memory managment.
Спасибо, почитаю.
← →
Тимохов (2004-02-02 19:14) [9]
> Palladin © (02.02.04 19:11) [7]
Когда-то давно была книга по дельфи 2.
Там на уровне асм. кода было расписано как работают строки.
Очень было познавательно. До сих пор многое от тудова помню.
Не знаю есть ли такие же книги по современным версиям дельфи.
← →
Palladin (2004-02-02 19:23) [10]
> Тимохов © (02.02.04 19:14) [9]
я не спорю, если человек определит свои требования к статье, к содержанию, то он без труда подберет ключевые слова для ее самостоятельного поиска...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.011 c