Есть локальный COM сервер на ATL.
Внутри используется WinHTTP, MSXML.
Сервер время от времени(до нескольких раз в минуту) качает xml-ку из интернета.
Данные, которые одновременно хранятся на сервере занимают 300-400 кб максимум(примерно).
вначале exe-шник занимает 3-4 метра.
в течении 2-3 часов он растет до 20-23 метров. потом освобождается до 10-12 и опять растет.
в сервере 80 длл я насчитал, но вначале их даже больше(смотрел process explorer-ом)
Собственно вопрос — можно ли найти причину такого роста памяти? может в WinHTTP есть какие-то буфера или файлы выгружаются из памяти не сразу...
Средствами отладки CRT — ликов нет. Для хендлов файлов используются умные указатели — тоже не должно быть ликов.
С COM объектами — тоже вроде все нормально, если бы количество AddRef/Release не совпадало — сервер бы зависал при выходе, такое уже было.
Здравствуйте, sidorov18, Вы писали:
S>Собственно вопрос — можно ли найти причину такого роста памяти?
Нужно убедиться что это не твое точно.
Скажем дампить количесвто и объем аллокаций и/или объектов.
S>может в WinHTTP есть какие-то буфера или файлы выгружаются из памяти не сразу...
Может сегодня есть, а может заватра уже нет. Т.е. тебе это знание ну никак не поможет.
Здравствуйте, c-smile, Вы писали:
CS>Нужно убедиться что это не твое точно. CS>Скажем дампить количесвто и объем аллокаций и/или объектов.
О.
А как это сделать? и можно ли при этом знать место(на стеке), где эта аллокация происходит.
S>>может в WinHTTP есть какие-то буфера или файлы выгружаются из памяти не сразу...
CS>Может сегодня есть, а может заватра уже нет. Т.е. тебе это знание ну никак не поможет.
Помогло бы локализовать рост памяти. знать, что это? политика ОС или настраиваемая фича.
Здравствуйте, sidorov18, Вы писали:
S>Здравствуйте, c-smile, Вы писали:
CS>>Нужно убедиться что это не твое точно. CS>>Скажем дампить количесвто и объем аллокаций и/или объектов.
S>О. S>А как это сделать? и можно ли при этом знать место(на стеке), где эта аллокация происходит. http://www.rsdn.ru/article/vcpp/leaks.xml
Здравствуйте, Guard_h4s, Вы писали:
G_>Здравствуйте, sidorov18, Вы писали:
S>>Здравствуйте, c-smile, Вы писали:
CS>>>Нужно убедиться что это не твое точно. CS>>>Скажем дампить количесвто и объем аллокаций и/или объектов.
S>>О. S>>А как это сделать? и можно ли при этом знать место(на стеке), где эта аллокация происходит. G_>http://www.rsdn.ru/article/vcpp/leaks.xml
Здравствуйте, sidorov18, Вы писали:
S>Здравствуйте, Guard_h4s, Вы писали:
G_>>Здравствуйте, sidorov18, Вы писали:
S>>>Здравствуйте, c-smile, Вы писали:
CS>>>>Нужно убедиться что это не твое точно. CS>>>>Скажем дампить количесвто и объем аллокаций и/или объектов.
S>>>О. S>>>А как это сделать? и можно ли при этом знать место(на стеке), где эта аллокация происходит. G_>>http://www.rsdn.ru/article/vcpp/leaks.xml
S>Спасибо, уже проверил — ничего нет(это я и имел ввиду в первом посте под "Средствами отладки CRT — ликов нет").
Ну тогда только менять WinHTTP остается.
Кстати, замеры делали по количеству виртуальной памяти или по физическим страницам?
Здравствуйте, Guard_h4s, Вы писали:
G_>Здравствуйте, sidorov18, Вы писали:
S>>Здравствуйте, Guard_h4s, Вы писали:
G_>>>Здравствуйте, sidorov18, Вы писали:
S>>>>Здравствуйте, c-smile, Вы писали:
CS>>>>>Нужно убедиться что это не твое точно. CS>>>>>Скажем дампить количесвто и объем аллокаций и/или объектов.
S>>>>О. S>>>>А как это сделать? и можно ли при этом знать место(на стеке), где эта аллокация происходит. G_>>>http://www.rsdn.ru/article/vcpp/leaks.xml
S>>Спасибо, уже проверил — ничего нет(это я и имел ввиду в первом посте под "Средствами отладки CRT — ликов нет"). G_>Ну тогда только менять WinHTTP остается. G_>Кстати, замеры делали по количеству виртуальной памяти или по физическим страницам?
Я делал только то, что описано в статье — объявлял макрос _CRTDBG_MAP_ALLOC. Делал тестовый лик, чтобы убедится, что все работает. по завершении программы — никаких ликов нет(В конце Leaks detected! не пишет в окне дебага).
Насчет памяти — смотрел только по диспетчеру задач) — эта колонка называется "Память(частный рабочий набор)" в 7-ке.
А что может дать распределение памяти по физической/виртуальной?
Насчет WinHTTP — локализовать хотябы, кто память выделяет.
какими средствами это можно сделать? можно, например, отслеживать каждое выделение памяти и знать при этом стек?
Re[7]: размер программы в памяти
От:
Аноним
Дата:
15.06.10 10:21
Оценка:
Здравствуйте, sidorov18, Вы писали:
S>Здравствуйте, Guard_h4s, Вы писали:
G_>>Здравствуйте, sidorov18, Вы писали:
S>>>Здравствуйте, Guard_h4s, Вы писали:
G_>>>>Здравствуйте, sidorov18, Вы писали:
S>>>>>Здравствуйте, c-smile, Вы писали:
CS>>>>>>Нужно убедиться что это не твое точно. CS>>>>>>Скажем дампить количесвто и объем аллокаций и/или объектов.
S>>>>>О. S>>>>>А как это сделать? и можно ли при этом знать место(на стеке), где эта аллокация происходит. G_>>>>http://www.rsdn.ru/article/vcpp/leaks.xml
S>>>Спасибо, уже проверил — ничего нет(это я и имел ввиду в первом посте под "Средствами отладки CRT — ликов нет"). G_>>Ну тогда только менять WinHTTP остается. G_>>Кстати, замеры делали по количеству виртуальной памяти или по физическим страницам?
S>Я делал только то, что описано в статье — объявлял макрос _CRTDBG_MAP_ALLOC. Делал тестовый лик, чтобы убедится, что все работает. по завершении программы — никаких ликов нет(В конце Leaks detected! не пишет в окне дебага).
То что не течет CRT еще не значит, что не течет что то другое
Нужно проверить еще COM память! Так же еще может течь какие-нить WinAPI функции требующие освобождения после использования, могут течь хэндлеры,....
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, sidorov18, Вы писали:
S>>Здравствуйте, Guard_h4s, Вы писали:
G_>>>Здравствуйте, sidorov18, Вы писали:
S>>>>Здравствуйте, Guard_h4s, Вы писали:
G_>>>>>Здравствуйте, sidorov18, Вы писали:
S>>>>>>Здравствуйте, c-smile, Вы писали:
CS>>>>>>>Нужно убедиться что это не твое точно. CS>>>>>>>Скажем дампить количесвто и объем аллокаций и/или объектов.
S>>>>>>О. S>>>>>>А как это сделать? и можно ли при этом знать место(на стеке), где эта аллокация происходит. G_>>>>>http://www.rsdn.ru/article/vcpp/leaks.xml
S>>>>Спасибо, уже проверил — ничего нет(это я и имел ввиду в первом посте под "Средствами отладки CRT — ликов нет"). G_>>>Ну тогда только менять WinHTTP остается. G_>>>Кстати, замеры делали по количеству виртуальной памяти или по физическим страницам?
S>>Я делал только то, что описано в статье — объявлял макрос _CRTDBG_MAP_ALLOC. Делал тестовый лик, чтобы убедится, что все работает. по завершении программы — никаких ликов нет(В конце Leaks detected! не пишет в окне дебага).
А>То что не течет CRT еще не значит, что не течет что то другое А>Нужно проверить еще COM память! Так же еще может течь какие-нить WinAPI функции требующие освобождения после использования, могут течь хэндлеры,....
Это все хорошо)
Можно ли это проверить программными средствами?
Тем более память время от времени очищается — можно предположить, что используются буфера, которые время от времени очищаются...
>Собственно вопрос — можно ли найти причину такого роста памяти? может в WinHTTP есть какие-то буфера или файлы выгружаются из памяти не сразу...
А в чем собственно сакральная ценность такого рода знания?
Если нужно понять есть ли утечки памяти я бы сделал по тупому — поставил на ночь (сутки, двое) работать и врубил perfmon на private set Вашего
процесса — если в результате тренд будет горизантальный (т.е. растет, падает до предыдущего уровня и снова) то волноваться не о чем.
Если растет и падает, но чуток выше чем было и так постоянно — то есть проблемы.
Для утечек COM памяти есть простенький StackWalker (наверное есть что то лучше, просто всегда его пользовал).
Для WinAPI незнаю ничего лучше чем проверить все места пользования.
Здравствуйте, sidorov18, Вы писали:
S>Это все хорошо) S>Можно ли это проверить программными средствами? S>Тем более память время от времени очищается — можно предположить, что используются буфера, которые время от времени очищаются...
while(1) в нужных местах и perfmon
Ничто не ограничивает полет мысли программиста так, как компилятор.
Здравствуйте, Аноним, Вы писали:
>>Собственно вопрос — можно ли найти причину такого роста памяти? может в WinHTTP есть какие-то буфера или файлы выгружаются из памяти не сразу... А>А в чем собственно сакральная ценность такого рода знания?
А>Если нужно понять есть ли утечки памяти я бы сделал по тупому — поставил на ночь (сутки, двое) работать и врубил perfmon на private set Вашего А>процесса — если в результате тренд будет горизантальный (т.е. растет, падает до предыдущего уровня и снова) то волноваться не о чем. А>Если растет и падает, но чуток выше чем было и так постоянно — то есть проблемы.
А>Для утечек COM памяти есть простенький StackWalker (наверное есть что то лучше, просто всегда его пользовал).
А>Для WinAPI незнаю ничего лучше чем проверить все места пользования.
А>Хэндлеры посмотреть в том же ProcessExlorer.
Спасибо) проверил.
Оставил на ночь работать программу.
На момент запуска монитора программа занимала 11 метров(это та память, что в диспетчере задач называется "Память", а по умолчанию там — "Память(частный рабочий набор)", которой меньше раза в полтора обычно).
Примерно за час объем памяти вырос до 20 метров. Дальше за минуту он упал до 2-х метров, а в след. минуту стал занимать 7 метров.
Через 40 минут объем вырос до 12-и метров.
А дальше включился ждущий режим.
Утром, после выхода из ждущего режима программа в памяти занимала почти 3 метра.
т.е. память время от времени очищается. это я заметил и раньше.
А если ждущий режим приводит к очищению памяти, то что это может быть? политика ОС? Если бы это были буфера WinHTTP, например — то они бы сохранились, наверное...
Хендлы смотрел через ProcessExplorer. Количество примерно одинаковое все время.
кроме моих файлов 3 файла, связанных с IE:
C:\Users\Дима\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\index.dat
C:\Users\Дима\AppData\Roaming\Microsoft\Windows\Cookies\index.dat
C:\Users\Дима\AppData\Local\Microsoft\Windows\History\History.IE5\index.dat
Здравствуйте, sidorov18, Вы писали:
S>т.е. память время от времени очищается. это я заметил и раньше. S>А если ждущий режим приводит к очищению памяти, то что это может быть? политика ОС? Если бы это были буфера WinHTTP, например — то они бы сохранились, наверное...
Ну все-таки вы видите только подгруженные странички(динамику их подгрузки/выгрузки). Реальной информации об использовании памяти это не дает. В таких случаях лучше смотреть количество виртуальной памяти для процесса(например в висте Commit size в таск менеджере). Это тоже не дает реальной инфы по использованию, но несколько ближе. Это значение если и уменьшается, то только если страницы освободили, а не выгрузили на диск.
Здравствуйте, Guard_h4s, Вы писали:
G_>Здравствуйте, sidorov18, Вы писали:
S>>т.е. память время от времени очищается. это я заметил и раньше. S>>А если ждущий режим приводит к очищению памяти, то что это может быть? политика ОС? Если бы это были буфера WinHTTP, например — то они бы сохранились, наверное... G_>Ну все-таки вы видите только подгруженные странички(динамику их подгрузки/выгрузки). Реальной информации об использовании памяти это не дает. В таких случаях лучше смотреть количество виртуальной памяти для процесса(например в висте Commit size в таск менеджере). Это тоже не дает реальной инфы по использованию, но несколько ближе. Это значение если и уменьшается, то только если страницы освободили, а не выгрузили на диск.
Спасибо)
Факт утечки, похоже, выявить все таки удалось.
После 16-и часов работы программы виртуальная память занимает 116 метров. И даже частный рабочий набор 54 метра(но скоро упал до 30-и).
Все же локализовать утечку не могу пока.
Вроде утечка происходит в процессе скачивания файла, т.к. если его не качать — то память стоит примерно на одном уровне все время.
В процессе скачивания файла:
Или текущий объем памяти записывается не синхронно или диспетчер задач ее обновляет не сразу, но в процессе выполнения ф-ии пошагово в отладчике увеличения памяти происходят в разных местах, хотя и регулярно( иногда на WinHttpOpen, иногда на условиях, вроде if(bool_variable) )
Может тут помогут всякие BoundsChecker? Никогда ими не пользовался.
И по поводу WinHTTP.
Я каждый раз заново создаю сессию через WinHttpOpen и в конце ф-ии закрываю ее хендл.
В msdn говорится, что с каждым вызовом WinHttpOpen создаются внутренние структуры данных. Может они не удаляются, когда закрывается хендл и стоит сделать каждую static __declspec(thread)?
Здравствуйте, sidorov18, Вы писали:
S>Все же локализовать утечку не могу пока.
AQTime, Rational Purify могут помочь
нужно в один момент узнать все аллокации, затем сделать какие-то действия, посмотреть аллокации в след момент
сделать diff глазами и узнать кто аллоцирует и не удаляет (это если не мемлики, а засасывание памяти идет)
мемлики тулзы сами покажут
Здравствуйте, sidorov18, Вы писали:
S>Может тут помогут всякие BoundsChecker? Никогда ими не пользовался.
По опыту могу сказать что достаточно капризная штука, далеко не с каждым проектом будет работать.
Хотя это относится к большинству анализаторов, если проект скажем на 1М строк...
Для мелких может вполне адекватно работать, надо пробовать
Re[13]: размер программы в памяти
От:
Аноним
Дата:
17.06.10 13:55
Оценка:
Здравствуйте, sidorov18, Вы писали:
S>И по поводу WinHTTP. S>Я каждый раз заново создаю сессию через WinHttpOpen и в конце ф-ии закрываю ее хендл. S>В msdn говорится, что с каждым вызовом WinHttpOpen создаются внутренние структуры данных. Может они не удаляются, когда закрывается хендл и стоит сделать каждую static __declspec(thread)?
Собственно в этом вся проблема и есть. По моим наблюдениям после закрытия хендла сессия уходит не сразу, порты еще некоторое остаются занятыми. Разбираться тогда в причинах не стал, а перешел на URL моникеры. Проблема испарилась.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, sidorov18, Вы писали:
S>>И по поводу WinHTTP. S>>Я каждый раз заново создаю сессию через WinHttpOpen и в конце ф-ии закрываю ее хендл. S>>В msdn говорится, что с каждым вызовом WinHttpOpen создаются внутренние структуры данных. Может они не удаляются, когда закрывается хендл и стоит сделать каждую static __declspec(thread)? А>Собственно в этом вся проблема и есть. По моим наблюдениям после закрытия хендла сессия уходит не сразу, порты еще некоторое остаются занятыми. Разбираться тогда в причинах не стал, а перешел на URL моникеры. Проблема испарилась.
А можно в 2-х словах об URL моникере? что это? полная альтернатива winInet/winhttp?
какие у них возможности? прокси само находит? https? POST запросы? хидеры можно запрашивать? можно ли контроллировать редиректы(каждый редирект самому получать)? и т.п.
Есть ли в сети какой пример класса с их использованием. сходу не нашел...
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, sidorov18, Вы писали:
S>>Все же локализовать утечку не могу пока. U>AQTime, Rational Purify могут помочь U>нужно в один момент узнать все аллокации, затем сделать какие-то действия, посмотреть аллокации в след момент U>сделать diff глазами и узнать кто аллоцирует и не удаляет (это если не мемлики, а засасывание памяти идет) U>мемлики тулзы сами покажут
Установил AQtime) Вы не подскажите, как в нем выполнить вышеуказанные действия. пока не разобрался как сделать точку останова. триггеры на код(ф-ю, которая к нету обращается) подобавлял, а как сделать, чтобы код остановился в указанной точке — не пойму.
Здравствуйте, sidorov18, Вы писали:
S>Есть ли в сети какой пример класса с их использованием. сходу не нашел...
Дело было 3 года назад, сразу и не нашел тот проект. В целом все просто, вот кусок кода, остальное в MSDN очень подробно описано.
По именам классов легко найдешь остальное, здесь очень маленькая часть.
// ---------------------------------------------------------------------- CDownload
// Класс реализующий обмен информацией между клиентом и сервером
class CDownload {
public:
CDownload();
~CDownload();