Существует ли приемлемый предел утечек памяти?

StackOverflow https://stackoverflow.com/questions/233258

  •  04-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

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

ХТХ.

ваше здоровье,

Роб

Другие советы

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

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

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

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

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

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

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

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

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

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

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

If ( средняя продолжительность сеанса) * (количество пропущенных байтов / минута) > 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), чтобы запретить вам беспокоиться об этих ошибках.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top