![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Out of memory после полумесяца работы программы.
Дмитрий Белькевич © (2011-06-07 10:46:00)Утечек памяти нет (судя по эврикалог). Out of memory случается где-то на 10-15 день работы приложения. Случается при попытке выделения памяти под динамический массив:
SetLength(FBuff16, AllocSLiceSz div 2);
AllocSLiceSz равен 31768000, т.е. выделяется около 31 мб.
Использую менеджер памяти FastMM.
Вопросов, как обычно, два - кто виноват и что делать...
CRLF (2012-04-05 22:43:00) [1]:-) Интересно. Из серии "Врачу, исцели себя сам".
Дмитрий Белькевич (2012-04-05 22:07:00) [2]Вспомнилось. Чтобы закрыть тему, может кому интересно будет... Eurekalog виновата была. EL версии 6.0.23 глючная была. Обновили - помогло.
>Кстати, рекомендую тулзу Process Explorer из SysInternals
Помог PE - стал виден расход виртуальной памяти. С глючной эврикой занимаемая виртуальная память быстро дорастала до 2х гиг и приложение падало.
Дмитрий Белькевич (2011-06-16 15:05:00) [3]Спасибо всем за интересные мысли. Отдал сегодня с включенными проверками range check, overflow check, в fastmm - full debug, по таймеру делаю 'ScanMemoryPoolForCorruptions': Scans the memory pool for any corruptions. If a corruption is encountered an "Out of Memory" exception is raised. Понаблюдаем в таком режиме...
Anatoly Podgoretsky (2011-06-16 13:13:00) [4]Не поможет, у него фрагментирована виртуальная память.
VirEx (2011-06-16 11:58:00) [5]>Дмитрий Белькевич (07.06.11 10:46) [0]
может время от времени инициировать сброс памяти в файл подкачки как это делает плагин для миранды когда она свернута в трей?
dred2k (2011-06-16 10:09:00) [6]
> Дмитрий Белькевич (15.06.11 23:57) [40]
Архитектура позволяет выделить веб из сервера ? Отдельным сервером, с межпроцессным взаимодействием (пайпы, к примеру, сокеты или даже сообщения). Если накладные расходы на разделение невелики, это может решить проблему уже в сжатые сроки.
Германн (2011-06-16 01:29:00) [7]
> Дмитрий Белькевич (15.06.11 23:57) [40]
Рекомендую обратить внимание на жесткий диск, как на память для хранения информации. Его хоть можно периодически дефрагментировать не останавливая программу.
Дмитрий Белькевич (2011-06-15 23:57:00) [8]
> Тут может быть _все что угодно_.
Вообще, замечено, что, вероятно, проблема в обработке веба. Сервер, среди прочего, имеет веб интерфейс к себе и генерирует (без сторонних приложений) некоторое количество - штук 30-40 разных страниц. Так вот - у нас на основном 'тестовом полигоне' сервер нормально работает месяцами, но мы у себя веб не используем. У одних из пользователей, по соглашению - бэта-тестеров - сервер используется полностью, с вебом в том числе. Это, правда, слабое утешение в поиске проблемы. Опять же - возможно, что именно веб дает сильную фрагментацию памяти. Мы пока что переползли на обновленный фаст мм, попробуем еще с ним поработать. Дальше буду пробовать фуллдебаг мод. Буду пробовать снимать карту памяти (вроде бы фаст мм позволяет) после out of memory (если удастся). Попробую еще какую-то информацию вытянуть из фастмм, если не удастся встроенными средствами - попробую фастмм дописать.
dred2k (2011-06-15 23:36:00) [9]Решил поэкспериментировать со строками. Как при операциях меняется указатель на первый элемент ?
Ниже - пример, для внутренней переменной. Если перенести ее в глобальную область - будет интереснее...
procedure TForm1.Button2Click(Sender: TObject);
var tmpStr : String;
begin
// Посмотрим, как изменяются указатели на первый символ
// одной и той же строки при некоторых операциях с последней.
with Memo1.Lines do
begin
Clear;
// Вариант 1
Add('Вариант 1');
tmpStr := '1234';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := tmpStr + '1234567';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := '1234567890';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
Add('------------------------------------');
// Вариант 2
Add('Вариант 2');
tmpStr := '1234';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := tmpStr + '12345678'; // <---- !!!!!!!!!!!!!!!!!!!!!
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := '1234567890';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
Add('------------------------------------');
// Вариант 3
Add('Вариант 3');
tmpStr := '1234';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := tmpStr + '1234567';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := '12345678901'; // <---- !!!!!!!!!!!!!!!!!!!!!
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
Add('------------------------------------');
// Вариант 4
Add('Вариант 4');
tmpStr := '1234';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := tmpStr + '1234567';
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
tmpStr := '123456789012'; // <---- !!!!!!!!!!!!!!!!!!!!
Add(IntToStr(Integer(@tmpStr[1])) + ' ["' + tmpStr + '"]');
Add('------------------------------------');
end;
end;
dred2k (2011-06-15 21:34:00) [10]Кстати, рекомендую тулзу Process Explorer из SysInternals, он показал в свойствах процесса Peek Private Bytes как раз равным размеру строки s - 800 с чем-то метров. При этом Virtual Size был около 65 метров.
Может подумать об использовании функций класса Virtualxxx ?
Быстрые гипотезы, сорри.
dred2k (2011-06-15 21:15:00) [11]На Delphi2007 тоже "волшебный" менеджер (я на тему [28]).
864272 (EOutOfMemory) = [865271000 - длина строки s]
Win7x64, 4 гига
dred2k (2011-06-15 20:56:00) [12]В чем у меня была сложность - падала NT-я. :)
dred2k (2011-06-15 20:55:00) [13]Советую настроить мониторинг приложения в мониторе ресурсов (системном). Промониторить все пулы памяти - выгружаемый, невыгружаемый и т.д. С записью в файл, потом - анализ. Было дело, с помощью этого выловил регулярные падения сервака по вине, как оказалось, стороннего драйвера (юзал ком-порты через шарилку - SAPS).
Тут может быть _все что угодно_. При современном уровне порой очень не очевидной интеграции. Кстати, а DLL используются в алгоритме ?
Дмитрий Белькевич (2011-06-09 15:43:00) [14]Позже вернусь к вопросу, попробую полную отладку в fastmm включить + поиск границ и иже. Возможно всё таки это не фрагментация, хотя я уверен процентов на 80.
han_malign (2011-06-09 10:16:00) [15]
> Простого рецепта, типа "освободи, когда станет ненужным" не существует.
- простой рецепт - как можно меньше вложенных динамических объектов...
В большинстве случаев, вложенные String прекрасно заменяются на String [адекватного размера ], а вложенные классы на статически размещенные структуры/объекты...
Loginov Dmitry (2011-06-08 21:12:00) [16]
> При этом под строку "s" выделено памяти 735085000 байт.
Кстати обманул, указал количество символов в строке, а не размер выделенной под нее памяти. В случае D2010 число нужно умножать на 2, поэтому получим ~ 1,5 ГБ.
Sha (2011-06-08 18:05:00) [17]> Loginov Dmitry © (08.06.11 16:18) [28]
> Что волшебного в менеджере памяти у D2010?
Не перемежает разнокалиберные запросы.
RWolf (2011-06-08 17:50:00) [18]у FastMM или менеджера D7 есть вызовы для определения максимального размера непрерывной области памяти, которая может быть выделена?
неплохо было бы мониторить это число при отладке, чтобы избежать сабжа.
sniknik (2011-06-08 17:27:00) [19]> Что волшебного в менеджере памяти у D2010?
а вроде что-то про "сборщик мусора" с какой то версии дельфи говорили... ?
вот оно волшебство то.
Loginov Dmitry (2011-06-08 16:18:00) [20]
> Вот такая процедура вылетает у меня (D7 без FastMM) на 1543
> проходе цикла,
D2010. 2ГБ ОЗУ. Ошибка возникает на 734085 итерации. При этом под строку "s" выделено памяти 735085000 байт. Что волшебного в менеджере памяти у D2010?