Есть ли приемлемый предел утечек памяти?

Я только начал экспериментировать с SDL в C++, и я думал, что регулярная проверка на утечки памяти может быть хорошей привычкой формироваться на ранних этапах.

Имея это в виду, я запускал свои программы "Hello world" через Valgrind для выявления любых утечек, и хотя я удалил все, кроме самых основных SDL_Init() а также SDL_Quit() Заявления, Valgrind по-прежнему сообщает о 120 потерянных байтах и ​​77k по-прежнему доступны

У меня вопрос: есть ли приемлемый предел для утечек памяти, или я должен стремиться сделать весь мой код полностью без утечек?

11 ответов

Решение

Будьте осторожны, что Valgrind не обнаруживает ложных срабатываний в своих измерениях.

Многие наивные реализации анализаторов памяти отмечают потерю памяти как утечку, когда это не так.

Возможно, прочитайте некоторые статьи в разделе внешних ссылок статьи Википедии о Purify. Я знаю, что документация, поставляемая с Purify, описывает несколько сценариев, в которых вы получаете ложные срабатывания при попытке обнаружить утечки памяти, а затем описывает методы, которые Purify использует для решения проблем.

Кстати, я никоим образом не связан с IBM. Я только что использовал Purify и буду ручаться за его эффективность.

Изменить: Вот отличная вводная статья, посвященная мониторингу памяти. Это специфично для Purify, но обсуждение типов ошибок памяти очень интересно.

НТН.

веселит,

обкрадывать

Вы должны быть осторожны с определением "утечки памяти". Что-то, что выделяется один раз при первом использовании и освобождается при выходе из программы, иногда будет отображаться детектором утечек, потому что он начал считать перед первым использованием. Но это не утечка (хотя это может быть плохой дизайн, так как он может быть неким глобальным).

Чтобы увидеть, не утечка ли у данного куска кода, вы могли бы разумно запустить его один раз, затем очистить детектор утечки, а затем снова запустить его (это, конечно, требует программного контроля детектора утечки). Вещи, которые "просачиваются" один раз за прогон программы, обычно не имеют значения. Вещи, которые "просачиваются" каждый раз, когда их выполняют, обычно имеют значение в конце концов.

Я редко обнаруживал, что слишком трудно достичь нуля по этой метрике, что эквивалентно наблюдению за использованием ползучей памяти в отличие от потерянных блоков. У меня была одна библиотека, в которой она оказалась настолько неудобной, с кешами и мебелью пользовательского интерфейса и так далее, что я просто трижды запускал свой тестовый набор и игнорировал любые "утечки", которые не возникали в виде кратных трех блоков. Я все еще улавливал все или почти все настоящие утечки и анализировал хитрые сообщения, как только я убрал низко висящий фрукт. Конечно, слабые стороны использования набора тестов для этой цели заключаются в том, что (1) вы можете использовать только те его части, которые не требуют нового процесса, и (2) большинство обнаруженных вами утечек являются ошибкой кода теста, а не код библиотеки...

Жизнь с утечками памяти (и другими неосторожными проблемами) в лучшем случае (на мой взгляд) очень плохое программирование. В худшем случае это делает программное обеспечение непригодным для использования.

Во-первых, вам следует избегать их введения и запускать инструменты, о которых вы и другие упоминали, чтобы попытаться их обнаружить.

Избегайте неаккуратного программирования - там уже достаточно плохих программистов - миру не нужен еще один.

РЕДАКТИРОВАТЬ

Я согласен - многие инструменты могут дать ложные срабатывания.

Если вы действительно беспокоитесь об утечке памяти, вам нужно будет сделать некоторые вычисления.

Вам нужно протестировать ваше приложение в течение часа, а затем вычислить утечку памяти. Таким образом, вы получите утечку памяти в байтах / минутах.

Теперь вам нужно будет оценить среднюю продолжительность сеанса вашей программы. Например, для notepad.exe 15 минут звучат как хорошая оценка для меня.

Если (средняя продолжительность сеанса)*(утечка байтов / минута) > 0,3 * (пространство памяти, обычно занимаемое вашим процессом), то вам, вероятно, следует приложить еще больше усилий для уменьшения утечек памяти. Я только что составил 0,3, используйте здравый смысл, чтобы определить ваш приемлемый порог.

Помните, что важным аспектом работы программиста является работа инженера-программиста, и очень часто инжиниринг заключается в выборе наименее худшего варианта из двух или более плохих вариантов. Математика всегда пригодится, когда вам нужно измерить, насколько плох вариант на самом деле.

Большинство ОС (включая Windows) вернут всю выделенную память программы, когда программа выгружена. Это включает в себя любую память, которую программа могла потерять.

Исходя из этого, моя обычная теория заключается в том, что утечка памяти во время запуска совершенно нормальна, но не в порядке во время выполнения.

Так что на самом деле вопрос не в том, утечка ли у вас памяти, а в том, постоянно ли она течет во время выполнения вашей программы. Если вы используете свою программу какое-то время, и независимо от того, что вы делаете, она остается потерянной, а не увеличенной на 120 байт, я бы сказал, что вы отлично справились. Двигаться дальше.

Для настольного приложения небольшие утечки памяти не являются реальной проблемой. Для сервисов (серверов) утечки памяти не допускаются.

Это зависит от вашего приложения. Некоторая утечка может быть неизбежной (из-за времени, необходимого для определения утечки по сравнению со сроками). Пока ваше приложение может работать столько, сколько вы хотите, и не занимать сумасшедший объем памяти в это время, это, вероятно, нормально.

Похоже, разработчики SDL не используют Valgrind, но я в основном забочусь только о тех потерянных 120 байтах.

Имея это в виду, я запускал свои программы "Hello world" через Valgrind для обнаружения любых утечек, и хотя я удалил все, кроме самых простых операторов SDL_Init() и SDL_Quit(), Valgrind по-прежнему сообщает о 120 потерянных байтах и 77к еще достижимо.

Что же касается Valgrind, то "все еще достижимая память" часто не является утечкой памяти, особенно в такой простой программе. Могу поспорить, что в SDL_Quit() распределение практически отсутствует, поэтому "утечки" - это просто структуры, выделенные SDL_Init() один раз.

Попробуйте добавить полезную работу и посмотреть, увеличатся ли эти суммы; попробуйте сделать цикл полезной работы (например, создать и уничтожить некоторую структуру SDL) и посмотреть, увеличивается ли количество утечек с количеством итераций. В последнем случае вы должны проверить в стеке следы утечек и исправить их.

В противном случае эти 77k утечек считаются "памятью, которая должна быть освобождена в конце программы, но для которой они полагаются на ОС для ее освобождения".

Так что, на самом деле, я сейчас больше обеспокоен этими 120 байтами, если они не являются ложными срабатываниями, а их обычно немного. Ложные срабатывания с Valgrind - это в основном случаи, когда предполагается использование неинициализированной памяти (например, потому что она на самом деле заполнена).

Согласно комментариям Роба Уэллса о Purify, скачайте и опробуйте некоторые другие инструменты там. Я использую BoundsChecker и AQTime, и я видел разные ложные срабатывания за оба года. Обратите внимание, что утечка памяти также может быть связана со сторонним компонентом, который вы можете исключить из анализа. Из примера, MFC имел ряд утечек памяти в первых версиях просмотра.

IMO, утечки памяти должны быть отслежены для любого кода, который входит в кодовую базу, которая может иметь долгую жизнь. Если вы не можете отследить их, хотя бы отметьте, что они существуют для следующего пользователя с тем же кодом.

В частности, в случае SDL для Linux в базовой библиотеке X windows, похоже, есть утечка. Вы ничего не можете с этим поделать (если только вы не хотите попытаться исправить саму библиотеку, что, вероятно, не для слабонервных).

Вы можете использовать механизм подавления valgrind (см. --Suppressions и --gen-suppressions на справочной странице valgrind), чтобы запретить вам беспокоиться об этих ошибках.

В общем, мы должны быть немного более мягкими со сторонними библиотеками; в то время как мы не должны полностью принимать утечки памяти в нашем собственном коде, и наличие утечек памяти должно быть фактором при выборе между альтернативными сторонними библиотеками, иногда нет другого выбора, кроме как игнорировать их (хотя может быть хорошей идеей сообщить о них сопровождающему библиотеки).

Постоянные утечки памяти - только серьезная проблема, когда они растут со временем, в противном случае приложение выглядит немного больше снаружи (очевидно, здесь тоже есть предел, отсюда и "серьезный"). Если у вас есть утечка, которая растет со временем, у вас могут возникнуть проблемы. Сколько проблем зависит от обстоятельств, хотя. Если вы знаете, куда идет память, и можете быть уверены, что у вас всегда будет достаточно памяти для запуска программы и всего остального на этой машине, у вас все равно все в порядке. Однако, если вы не знаете, куда идет память, я не стал бы отправлять программу и продолжать копать.

Другие вопросы по тегам