Форум: "Начинающим";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];
ВнизЧастый вызов SetLength(Count+10) Найти похожие ветки
← →
@!!ex © (2007-12-02 19:18) [0]Может ли вызвать ошибку?
Просто есть контейнер, доюалвение в который реализовано так:procedure TNoise.Add(Position:TVector; LifeTime:integer; bSize:single; Const Color:TVector);
begin
inc(Count);
if Count>Size then begin
inc(Size,500);
SetLength(Items,Size);
end;
Items[Count-1]:=TWaterNoise.Create(Position,LifeTime,bSize,Color);
end;
И при этом в него засовывается около 500 объектов.
Проект начал падать, есть основания полагатЬ, что ошибка в контейнере.
Но там ничего страшщного не происходит, кроме такого фигового ресайза массива.
← →
@!!ex © (2007-12-02 19:19) [1]опечатка.
inc(Size,10);
← →
Amoeba © (2007-12-02 19:41) [2]А какой смысл использовать динамический массив объектов вместо TObjectList?
← →
@!!ex © (2007-12-02 20:00) [3]> [2] Amoeba © (02.12.07 19:41)
То что я не знал о его существовании, когда писал все это.
Сейчас переделывать поздно, ибо завтра сдавать готовый проект надо.
← →
Правильный_Вася (2007-12-02 20:30) [4]я когда-то в Д5 сталкивался с проблемами дин массивов
если добавлять мелкими порциями много тысяч элементов, то иногда на AV выпадал
TList не имеет такой бяки
← →
Сергей М. © (2007-12-03 09:05) [5]
> Может ли вызвать ошибку?
Может.
← →
Slym © (2007-12-03 09:13) [6]добавление простое и в нем ошибки нет... а вот удалении смотреть нужно, т.к там не все просто и гладко
← →
Riply © (2007-12-03 09:32) [7]> [5] Сергей М. © (03.12.07 09:05)
> Может.
Я понимаю, что "краткость - сестра" :),
но все таки, можно по-подробнее ?
← →
Сергей М. © (2007-12-03 09:38) [8]
> Riply © (03.12.07 09:32) [7]
Все просто - частое перераспределение памяти ведет к ее дефрагментации, если менеджер памяти не поддерживает (или не полной мере поддерживает) сборку мусора.
← →
Сергей М. © (2007-12-03 09:38) [9]
> дефрагментации
К фрагментации, конечно же)
← →
Riply © (2007-12-03 09:45) [10]> [8] Сергей М. © (03.12.07 09:38)
Спасибо.
Но тогда виноват не бедный SetLength, а не совсем правильная работа с памятью.
Так что с него можно снять такие тяжкие обвинения :)
← →
Leonid Troyanovsky © (2007-12-03 09:57) [11]
> Riply © (03.12.07 09:45) [10]
> Но тогда виноват не бедный SetLength, а не совсем правильная
> работа с памятью.
Тогда тяжкие обвинения лягут на дельфийский менеджер памяти :)
Скорее всего, автор чего-то не договаривает,
может он, например, потоки использует.
--
Regards, LVT.
← →
MBo © (2007-12-03 10:30) [12]В BDS2006 сей код отрабатывает без проблем - линейный рост занимаемой процессом памяти, а вот в старых версиях, насколько я помню, менеджер памяти мог не успевать, и рост квадратичный, пока не кончится память. Кто-нибудь проверит на 5-6-7?
procedure TForm2.Button8Click(Sender: TObject);
var
i, s: Integer;
a: array of Integer;
begin
s := 0;
for i := 1 to 100000000 do begin
SetLength(a, i);
s:= s + a[0];
end;
Caption := IntToStr(s);
end;
← →
Сергей М. © (2007-12-03 10:38) [13]
> MBo © (03.12.07 10:30) [12]
D7 - полет нормальный.
← →
sniknik © (2007-12-03 10:40) [14]> Кто-нибудь проверит на 5-6-7?
D7, отработало без ошибок, результат в Caption-е 0.
← →
MBo © (2007-12-03 11:33) [15]ОК, значит, и старый менеджер памяти отлично справлялся с инкрементальным увеличением дин. масива.
← →
Правильный_Вася (2007-12-03 11:36) [16]
> D7 - полет нормальный.
может зависеть от скорости тачки
← →
Сергей М. © (2007-12-03 11:53) [17]
> может зависеть от скорости тачки
Причем здесь "скорость тачки" ?
Сборка мусора в ММ Д7 - операция синхронная
← →
Anatoly Podgoretsky © (2007-12-03 11:57) [18]> Сергей М. (03.12.2007 11:53:17) [17]
А она есть?
← →
Сергей М. © (2007-12-03 12:03) [19]
> Anatoly Podgoretsky © (03.12.07 11:57) [18]
Есть, примитивная.
Тривиальная попытка объединения освобождаемого блока со смежными свободными блоками.
← →
Anatoly Podgoretsky © (2007-12-03 12:03) [20]> MBo (03.12.2007 10:30:12) [12]
Это не корректный тест, здесь просто происходит расширение массива, а поскольку блоки выше свободны, то без пересылки в новый блок памяти. Вот если в цикле что ни будь включить, что бы память нельзя было расширить, то рост будет квадратичный и будет отражать реальные ситуации. Например удлинение размера строки, на размер более например 16 символов.
st := "";
for i := 1 to 100000000 do begin
SetLength(a, i);
s:= s + a[0];
st := st + "12345678901234567890";
end;
← →
SergeyIT © (2007-12-03 12:29) [21]В Д5
[12] - без проблем.
[20] - ошибка - OutOfMemory.
← →
antonn © (2007-12-03 13:58) [22]
> Anatoly Podgoretsky © (03.12.07 12:03) [20]
в D7 - OutOfMemory (сожрала гиг оперы и почти полтора гига из свапа)
:(
← →
@!!ex © (2007-12-03 14:04) [23]Косяк был дейтствительно не тут...
еще раз убеждаюсь, что надо 10 раз все проверить, прежде чем исправить давно и успешно работающий код.
Причем на такие грабли уже наткыался, и опять...
← →
MBo © (2007-12-03 14:06) [24]to 100 000 000 - многовато, конечно - строка в 2 гигабайта получится
А в 10 раз меньше - нормально - при своевременном освобождении памяти не более гига понадобится
← →
Leonid Troyanovsky © (2007-12-03 14:11) [25]
> MBo © (03.12.07 10:30) [12]
> я помню, менеджер памяти мог не успевать,
> SergeyIT © (03.12.07 12:29) [21]
> [20] - ошибка - OutOfMemory.
> antonn © (03.12.07 13:58) [22]
> в D7 - OutOfMemory
Это, конечно, здорово, но OOM это, все же, не AV.
Может, до открытия новых обстоятельств,
отпустим ММ на поруки?
--
Regards, LVT.
← →
sniknik © (2007-12-03 14:11) [26]> в D7 - OutOfMemory (сожрала гиг оперы и почти полтора гига из свапа)
всего 2 гига? так это нормально, st := st + "12345678901234567890"; повторенная 100000000 раз, сделает строку как раз под 2 гига.
а для того чтобы выделить под новое добавление, еше такой же размер + 20 вот тут и OutOfMemory.
← →
Сергей М. © (2007-12-03 14:22) [27]
> на такие грабли уже наткыался, и опять
На то они и грабли, бледнолицый)
← →
Sapersky (2007-12-03 15:16) [28]Примерно 2 месяца назад была ветка "Резкое увеличение размера динамического массива", но, похоже, ушла в архив.
Там пример перебора всех файлов на диске с SetLength(Arr, Count + 1) вылетал по OutOfMemory.
← →
Anatoly Podgoretsky © (2007-12-03 18:55) [29]Как я вас поймал с примером :-)
Конечно цикл надо уменьшить минимум в два раза.
← →
Kolan © (2007-12-03 19:03) [30]> То что я не знал о его существовании, когда писал все это.
> Сейчас переделывать поздно, ибо завтра сдавать готовый проект
> надо.
А что массив объектов оч. сложно переделать на TObjectList? Изменить Add и все, а обрашение точно такой же синтаксис имеет…
← →
SergeyIT © (2007-12-03 19:05) [31]> Как я вас поймал с примером
Нормальный тест. Просто try ... except поставить надо и освободить память.
← →
Anatoly Podgoretsky © (2007-12-03 19:25) [32]Да просто тест требует свыше 2 гб памяти, даже без учета фрагментации.
← →
Loginov Dmitry © (2007-12-03 22:49) [33]> [20] Anatoly Podgoretsky © (03.12.07 12:03)
D7: 20 минут пришлось ждать, пока счетчик достигнет значения 10000000 (был выставлен "высокий" приоритет). Заняло ок. 400Мб оперативки. Не свалилось. Видимо, вероятность возникновения OutOfMemory как-то зависит от производительности железа (тестировалось на Athlon 64 X2 Dual 4600+ 2ГБ ОЗУ).
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.01 c