Комментарии 45
непонятно какая платформа имеется ввиду и какой компилятор в разделе «Час расплаты». Может вы подразумеваете наличие одной платформы, одной ОС и одного компилятора? тогда поделитесь пожалуйста, а то я мож отстаю от времени.
По поводу предложеного метода, думаю не очень пригоден для больших проектов, предпочитаю Valgrind для отладки и «умные указатели» в качестве реализации, естественно где это уместно и оправдано.
По поводу предложеного метода, думаю не очень пригоден для больших проектов, предпочитаю Valgrind для отладки и «умные указатели» в качестве реализации, естественно где это уместно и оправдано.
+3
Спасибо за замечание; при тестировании использовалось MSVC9 на Vista SP2. Тот же порядок (но немного бОльшие цифры) выходят для тестового приложения запущенного на XP SP3. «Час расплаты» целиком относится только к Win32.
Да, для больших (хотя это понятие для каждого своё) проектов этот метод не пригоден, согласен. А «умные указатели» тоже не стоит воспринимать как панацею, от «лишнего» add reference они не застрахованы (человеческий фактор), а найти его иногда крайне сложно (а, интересно, Valgrind справится? особенно меня интересует эта проблема для CComPtr).
Да, для больших (хотя это понятие для каждого своё) проектов этот метод не пригоден, согласен. А «умные указатели» тоже не стоит воспринимать как панацею, от «лишнего» add reference они не застрахованы (человеческий фактор), а найти его иногда крайне сложно (а, интересно, Valgrind справится? особенно меня интересует эта проблема для CComPtr).
0
CComPtr никогда не пользовался и не представляю как он устроен. Но полюбому поможет, так как память выделяет и освобождает сам Valgrind (я незнаю работает ли он с визуалстудией или ему нужен обязаельно POSIX, но мне кажется, что ему нужен POSIX и для Visual Stusio он получается непригоден, но не уверен),
Вообще есть автоматиеские указатели, которы разрушают объект, когда последний из указателей выходит за область видимости. Много есть инструментов в Boost, Qt и новой спецификации С++. Могу сказать только про Qt, так как глубоко разбирался только с ними, при правильном подходе — можно спастить практически полностью от человеческого фактора.
Вообще есть автоматиеские указатели, которы разрушают объект, когда последний из указателей выходит за область видимости. Много есть инструментов в Boost, Qt и новой спецификации С++. Могу сказать только про Qt, так как глубоко разбирался только с ними, при правильном подходе — можно спастить практически полностью от человеческого фактора.
0
Если взять за практику такой порядок, когда объект сам прибирает за своими детьми, то потребность в ручных delete сократится почти до нуля. Но тем не менее даже в этом случае бывают очень странные утечки %).
>Вообще есть автоматиеские указатели, которы разрушают объект, когда последний из указателей выходит за область видимости.
Это если в памяти не висит какой-то объект, который вроде бы и в зоне видимости находится, но нафиг уже не нужен в общем то. Часто же и такое бывает. А тут ни какие анализаторы, вообще ничего не поможет, кроме владения ситуацией
>Вообще есть автоматиеские указатели, которы разрушают объект, когда последний из указателей выходит за область видимости.
Это если в памяти не висит какой-то объект, который вроде бы и в зоне видимости находится, но нафиг уже не нужен в общем то. Часто же и такое бывает. А тут ни какие анализаторы, вообще ничего не поможет, кроме владения ситуацией
+1
Был уверен, что Debug-конфигурация проекта делает это самостоятельно. По крайней мере, в MSVS6.0 после смерти программы можно было посмотреть output и увидеть, кто где выделил и не собрал.
А по поводу сборщиков мусора — фиг его знает, не определился: консервативные сборщики мусора — г##но в случае c с++, более агрессивные сканирующие — опасно, могут номер телефона в данных принять за ненужный указатель и «убрать».
А по поводу сборщиков мусора — фиг его знает, не определился: консервативные сборщики мусора — г##но в случае c с++, более агрессивные сканирующие — опасно, могут номер телефона в данных принять за ненужный указатель и «убрать».
0
Valgrind вам в руки. Или, на худой конец, google heap checker.
+4
Google heap checker насколько я понял только под Linux. А вообще, насколько бы ни были хороши внешние инструменты, тут рассматривается несколько другая задача — можно назвать это самодиагностикой. Отдав программу на предрелизное тестирование, например, мы убедимся, что у программы нет серьезных утечек. А если вдруг есть, то и поймем — где они. Главное, тестеров не придется учить новым штукам. Для маленьких проектов это актуально.
+1
Аналогичными define-ами можно обернуть открытие/закрытие сокетов, файловых дескрипторов и еще разных ресурсов выделение. Но вообще валгринд отлично все ловит, заодно детектит некорректые чтения/записи, неициализированные данные, если, конечно программа с ним совместима.
+2
В данном случае необходимость переопределения new имеет исторические корни, не в этом смысл. А Debug CRT тоже имеет средства обнаружения неициализированных данных (и обращений к уже освобожденным), выходов за границы массива. В сочетании с AppVerifier можно обрабатывать и попытки чтения/записи по неверным адресам. А вообще, Windows-программисты тоже должны как-то жить :)
0
dmalloc, valgrind под Linux
0
а с чего вы взяли, что www.hpl.hp.com/personal/Hans_Boehm/gc/ снижает производительность?
судя по этому посту max630.livejournal.com/131587.html и коду, приведенном в нем, который я сегодня затестил, boehm GC работает быстрее, чем ручные delete
судя по этому посту max630.livejournal.com/131587.html и коду, приведенном в нем, который я сегодня затестил, boehm GC работает быстрее, чем ручные delete
0
Ну это не совсем честное сравнение. Фактически, в том посте рассматривается ситуация, когда выделяется множество динамических объектов небольшого размера, а затем все они убиваются за раз.
В таких случаях вообще можно порекомендовать какой-нибудь boost::pool и не париться.
В общем же случае, конечно, сборщик мусора снижает производительность, потому что это некоторый нетривиальный алгоритм, требующий времени на выполнение, я так понимаю. А хуже всего то, что он может вызвать неравномерность выполнения: 30 секунд полёт нормальный, потом он решил почистить память — и 30 секунд ещё висим.
В таких случаях вообще можно порекомендовать какой-нибудь boost::pool и не париться.
В общем же случае, конечно, сборщик мусора снижает производительность, потому что это некоторый нетривиальный алгоритм, требующий времени на выполнение, я так понимаю. А хуже всего то, что он может вызвать неравномерность выполнения: 30 секунд полёт нормальный, потом он решил почистить память — и 30 секунд ещё висим.
+2
Субъективно очень даже снижает. Вообще надо бы взяться и оттестить, а то тезис
>Он, оказывается, работает быстрее, чем ручные delete. Раза в полтора.
немного удивляет и, быть может, подвох в чем-то другом.
>Он, оказывается, работает быстрее, чем ручные delete. Раза в полтора.
немного удивляет и, быть может, подвох в чем-то другом.
-1
статья «люди, не надо писать правильно на с++ и придумывать „костыли/велосипеды“! Используйте true дебаг тулзы!»
-2
НЛО прилетело и опубликовало эту надпись здесь
могу обе руки дать, что в моем коде они есть. Специально оставил, что в будущем «покопаться» :)
0
читаем саттера и учимся писать без ашипок…
-2
это я про то, что (цитата из статьи которую комментируем)
Не допускать ситуации вроде бы и не трудно — воспользуемся правилом «класть на место всё что взяли», но на практике это сильно осложняется человеческим фактором (банальная невнимательность), хитростью архитектуры и нелинейным порядком выполнения операторов, например, из-за применения исключений.
это не только не трудно, но большей частью абсолютно не накладно для рабочего кода. А уж исключения то просто обязаны заставлять вас писать ПРАВИЛЬНО, а не использовать дебаг тулзы для поиска мест «где же я еще прокосячил»
Не допускать ситуации вроде бы и не трудно — воспользуемся правилом «класть на место всё что взяли», но на практике это сильно осложняется человеческим фактором (банальная невнимательность), хитростью архитектуры и нелинейным порядком выполнения операторов, например, из-за применения исключений.
это не только не трудно, но большей частью абсолютно не накладно для рабочего кода. А уж исключения то просто обязаны заставлять вас писать ПРАВИЛЬНО, а не использовать дебаг тулзы для поиска мест «где же я еще прокосячил»
-3
Должен, однако, предупредить, что _CrtDumpMemoryLeaks может и врать. В проекте, над которым я сейчас работаю, он выдаёт дамп в сотни тысяч строк, тогда как сторонний полноценный профайлер выдаёт гораздо меньше утечек, и те большей частью в реализации строк в MFC/ATL. При этом отмечу, что студия не находит место выделения памяти в исходниках при клике на строках дампа, созданного функцией _CrtDumpMemoryLeaks.
0
_CrtDumpMemoryLeaks может врать только в одном ключе — он пропускает объекты выделенные вручную через HeapAlloc, GlobalAlloc. Как отсечь глобальные и статические объекты я написал, и да, их использованием MFC, увы, славится. Строку и имя файла определяет, если переопределить new, но «прыгать» по ней не будет. Но и время анализа и исправления утечки обычно больше, чем навигации по коду, всё-таки.
0
Да нет, врать он и по-другому умеет — сообщает о несуществующих утечках, и никакой ссылки на место в исходниках не выдаёт. просто пишет «утекло столько-то байтов» и дампит кусочек памяти. Как раз отсутствие таких ссылок и является одной из причин считать эти утечки ложными. Другая причина — сторонний профайлер ничего о них не сообщает.
+1
Всегда пользовался AQTime'ом, гораздо проще и пока ни разу не подводил. И ему можно верить, сервер работает месяцами — никаких ликов не обнаружено.
0
Недопонял, как эту фишку можно поюзать, скажем, в готовом проекте, во время выполнения которого все время в памяти находится большое число связанных объектов (например, 3д игрушка с физикой — там будет куча моделек, текстур, сущностей, связанных между собой и взаимодействующих с их физическими моделями). Я так понял, что эта фича позволяет снять дамп памяти, в котором каждый объект несет информацию о том, где он был аллоцирован. Но как это поможет, если мы не в состоянии отделить зерна от плевел, т.е. объекты, которые должны быть живы, от тех, которые должны были быть уничтожены на момент снятия дампа?
0
Это реализуется при помощи _CrtMemCheckpoint, _CrtMemDumpAllObjectsSince (про это было) и _CrtMemDifference, про которую не упомянул, наверное зря.
А вообще идеология простая, перед открытием проекта/сцены/модели делаем _CrtMemCheckpoint, после закрытия — _CrtMemDumpAllObjectsSince. Все новосозданные и не удаленные объекты являются подозрительными на утечку (но не обязаны ей быть).
А вообще идеология простая, перед открытием проекта/сцены/модели делаем _CrtMemCheckpoint, после закрытия — _CrtMemDumpAllObjectsSince. Все новосозданные и не удаленные объекты являются подозрительными на утечку (но не обязаны ей быть).
+1
Ага, я невнимателен, спасибо.
//
Жаль только, что можно работать только с одним, глобальным пулом памяти. Было бы здорово научиться выделять для различных групп объектов различные пулы памяти (прописывать имена пулов в классах), и затем сравнивать состояния в контрольных точках конкретных пулов. Это, мне кажется, упростило бы локализацию утечек.
//
Жаль только, что можно работать только с одним, глобальным пулом памяти. Было бы здорово научиться выделять для различных групп объектов различные пулы памяти (прописывать имена пулов в классах), и затем сравнивать состояния в контрольных точках конкретных пулов. Это, мне кажется, упростило бы локализацию утечек.
+1
И это тоже возможно средствами debug CRT, за счет более хитрого переопределения
new
. От способа веет «велосипедностью», и я боюсь, что любители внешних анализаторов совсем разозлятся — но, если кому-то интересно, могу рассказать, как это делается. 0
Расскажите в двух словах без деталей, если не трудно.
Мне приходит в голову либо добавить в структуру, оборачивающую выделенную память, свое собственное поле, в котором хранить ID пула, и задать макрос new для каждой группы классов, которые будут использовать этот пул. Это навряд ли получится, так как структура внутренняя.
Либо переопределить глобальный оператор new и уже с указателем, полученным из alloc'a, связать информацию о пуле. Соответственно, при выводе информации об утечках нужно каким-то способом прицепить туда эту информацию, выводя статистику по нужным пулам, или группируя.
Мне приходит в голову либо добавить в структуру, оборачивающую выделенную память, свое собственное поле, в котором хранить ID пула, и задать макрос new для каждой группы классов, которые будут использовать этот пул. Это навряд ли получится, так как структура внутренняя.
Либо переопределить глобальный оператор new и уже с указателем, полученным из alloc'a, связать информацию о пуле. Соответственно, при выводе информации об утечках нужно каким-то способом прицепить туда эту информацию, выводя статистику по нужным пулам, или группируя.
0
ответ по птатформе: это Вин32
для никс платформы что либо лучшее валгринда найти тяжело
для макоси — есть cвой анализатор, для солярки свой (признаюсь с соляркой не работал, но на Конференции SunTechDays долго общался на тему утечек с разработчиками OpenSolaris)
но если подойти к программированию теоретически, то есть пара простых правил по работе с выделением памяти:
выделение ресурса, в том числе памяти — делается в конструкторе, освобождение в деструкторе.
Используем «умные» (интеллектуальные) указатели.
если соблюдаем правила, то, как правило, утечек не бывает. Хотя, пройтись валгриндом по приложению — святое дело.
для никс платформы что либо лучшее валгринда найти тяжело
для макоси — есть cвой анализатор, для солярки свой (признаюсь с соляркой не работал, но на Конференции SunTechDays долго общался на тему утечек с разработчиками OpenSolaris)
но если подойти к программированию теоретически, то есть пара простых правил по работе с выделением памяти:
выделение ресурса, в том числе памяти — делается в конструкторе, освобождение в деструкторе.
Используем «умные» (интеллектуальные) указатели.
если соблюдаем правила, то, как правило, утечек не бывает. Хотя, пройтись валгриндом по приложению — святое дело.
+1
с ними (утечками) не надо бороться
их надо — не допускать!
их надо — не допускать!
-2
да нет, сама статья мне понравилась тоже
просто утечки надо не допускать, не знаю почему такая нервная реакция у минусеров :)
просто утечки надо не допускать, не знаю почему такая нервная реакция у минусеров :)
0
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре , чтобы оставить комментарий
Боремся с утечками памяти (C++ CRT)