![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| zedx |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
Собственно, ситуация: в проекте очень активно используются переменные TMemoryStream, причём само приложение многопоточное. (приложение - прокси-сервер, многопоточность - за счёт Indy (TIdHTTPServer)). Переменные создаются и уничтожаются как обычно:
За потоками Indy следит сам. Утечки и все исключения мониторю в EurekaLog, собственно, утечек памяти она не фиксирует. В процессе активного использования программы неумолимо растут затраты как оперативки, так и виртуальной памяти (мониторю в диспетчере винды). Оперативы у меня 1,5Гб, файл подкачки отключён полностью. Оперативку периодически, по таймеру, высвобождаю процедурой:
поставил таймер на 15 минут, к этому времени приложение успевает отхватить 250-300Мб озушки и почти столько же виртуальной памяти (при старте приложения используется всего - 10-15Мб). После вызова указанной процедуры оперативка высвобождается вся - приложение начинает занимать всего 1,5-3Мб, а вот виртуальная память растёт и дальше. И через определённое время, когда у винды виртуальная память кончается, моё приложение благополучно уничтожается (то-ли само вылетает, то-ли винда помогает)... Так вот, как подчищать виртуальную память, на подобии оперативки? И почему, вообще, память растёт, а не освобождается автоматом, коль уж утечек нет? |
||||
|
|||||
| kami |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Вполне возможно, что утечки не фиксируются благодаря тому, что используемая память высвобождается при завершении приложения. А при работе - просто добавляются новые данные. Пример:
Если процедура с этим циклом будет выполняться многократно - будет жесть. А утечек не будет, потому что в finalization будет код:
Просмотрите свой код - наверняка что-то подобное есть. |
||||||
|
|||||||
| zedx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
Нет, блоков finalization в проге вообще нет, и по завершении тоже ничего не освобождаю.
К тому же, если бы была ситуация как ты говиришь, то оперативка так глобально не освобождалась бы? Вот тут эта прога с исходниками, может кто глянет опытным глазом? |
|||
|
||||
| kami |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Да при чем тут finalization? Это было приведено в качестве явного примера возрастания потребления памяти вплоть до вылета, без явных утечек. освобождение может проходить где угодно - OnClose, Destroy и т.п. при завершении приложения. Ну, не могу сказать, что глаз у меня опытный, но посмотрим. |
|||
|
||||
| zedx |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
Да я понял, но нету такого. При завершении приложения освобождаю мелочь - критические секции, и собственно, Indy - т.е. то, что создавалось при старте проги. А всё, что в процессе создаётся, в процессе же и уничтожаю... единственно, вот сюда приходит последняя переменная Resp.Body (TMemoryStream) которую я не уничтожаю - её по-идее должен инди освободить... все остальные стримы для этого потока, к этому моменту уже уничтожаются.
Это сообщение отредактировал(а) zedx - 18.5.2009, 22:07 |
||||
|
|||||
| zedx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
Самое интересное, что диспетчер задач винды, не обращает внимание на то, что происходит очистка озушки и в Хронологии использования файла подкачки (хотя повторюсь - файл подкачки отключён) - такая ровная восходящая линия, до момента выбрасывания/зависания проги... причём сама винда и проги не тормозят ничуть, т.е. опреративка-то свободна. А вот запуск фотошопа, в момент когда прога выжрала всю виртуалку, обломился, с ошибкой фотошопа - Файл подкачки слишком мал, для завершения операции. Странно это.
|
|||
|
||||
| CodeMonkey |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 38 Всего: 89 |
Да ничего странного у вас нет. У вас либо нет утечки, но ошибка в логике (kami пример указал), либо утечка не памяти, а, скажем, объектов ядра (пример: создавать и не освобождать HBITMAP).
Если первое - попробуйте захавать как можно больше памяти, потом сделать дамп выделения (в этом вам поможет FastMM). Ткните наугад в карту памяти - с хорошей вероятностью получите виновника неявной утечки. Если второе - то кроме mem-leak используйте другие утилиты - профайлеры ресурсов. А EL какая версия? Я помню там баг когда-то был с детектом mem-leak-ов. Попробуйте ещё под FastMM или обновите EL до 6.0.20. Добавлено @ 23:34 Да, кстати, после того, как разберётесь с проблемой, выкиньте вот это: SetProcessWorkingSetSize(MainHandle, DWORD(-1), DWORD(-1)); Это сообщение отредактировал(а) CodeMonkey - 18.5.2009, 23:35 -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
| zedx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
||||
|
||||
| kami |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
При наличии 15 вызовов VirtualAlloc потребление памяти от вызовов этой ф-и достигло высот в 18353952 байт.
На 18-м программа скончалась. MemProof упрямо говорит, что проблема в выделении памяти. А именно: function PutFileToCache => X:=TSaveX.Create(true); // показывает пальцем сюда. И гораздо больше - просто вызов из function PutFlatFile => PutFileToCache. // и сюда Который, кстати, идет в двух местах этой процедуры. Это сообщение отредактировал(а) kami - 19.5.2009, 00:09 |
|||
|
||||
| zedx |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
т.е. поток не уничтожается? вот этот класс
и его процедура:
Это сообщение отредактировал(а) zedx - 19.5.2009, 00:18 |
||||||
|
|||||||
| kami |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
1. Пройдитесь отладчиком - я не могу скомпилировать код, т.к. не пользуюсь инди. А ковырять чужой код... ладно бы минимальный тестовый пример, в котором проявляется ошибка, а полный код 2. Скачайте себе профайлер и посмотрите сами что да как. |
|||
|
||||
| CodeMonkey |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 38 Всего: 89 |
-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
| zedx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
Поставил AQTime v6.20, интегрировался он в проект. Выбираю подозрительный модуль (с точки зрения утечки), правый клик мышью -> Profile xxx.pas В настройках выбрал профиль Allocation Profile. Запускаю, гоняю, вижу утечку в Диспетчере задач, закрываю прогу. AQT выдаёт мне репорт:
Очень много строчек VCL native memory - но размер мизерный, а вот 2 последние строчки: Reserved Virtual Memory - по 5 Мб - я так понимаю, это и есть утечка, т.к. строчек Committed после не наблюдается? Не понимаю, как перейти теперь по этой инфе (Address 0x08010000) в исходники, на конкретную строку/процедуру, где эта утечка происходит... Что делать? |
|||
|
||||
| zedx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 63 Регистрация: 29.11.2007 Репутация: нет Всего: нет |
Похоже, что нашел основную утечку (правда, методом тыка - по-этапно исключая из кода то, что можно отключить. Как находить утечки с AQTime так и не выяснил). Виновником оказался визуальный компонент от TMS: AdvStringGrid. Я использую его для динамического добавления строк+раскраска (причём всё это происходит из потока).
Помогло исключение из кода строчек:
... и как мне теперь, интересно, строки писать? Это сообщение отредактировал(а) zedx - 21.5.2009, 12:56 |
|||
|
||||
| kami |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Нехорошо обращаться к визуальным компонентам из потока. Сделать это хотя бы из метода синхронизации потока. Поэтому и могут идти утечки. А исходный код компонентов доступен? Добавлено через 1 минуту и 25 секунд Тоже не помогу. Для этой цели использую исключительно FastMM, а AQ - для замера производительности сложных участков кода. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |