Утечка памяти

Поделись знанием:
Перейти к: навигация, поиск

Уте́чка па́мяти (англ. memory leak) — процесс неконтролируемого уменьшения объёма свободной оперативной или виртуальной памяти компьютера, связанный с ошибками в работающих программах, вовремя не освобождающих ненужные уже участки памяти, или с ошибками системных служб контроля памяти.





Что такое утечка памяти

Рассмотрим следующий фрагмент кода на C++:

/*1*/ char *pointer = NULL;
/*2*/ for( int i = 0; i < 10; i++ ) {
/*3*/   pointer = new char[100];
/*4*/ }
/*5*/ delete [] pointer;

В этом примере на 3-й строке создается объект в динамической памяти. Код на 3-й строке выполняется 10 раз, причём каждый следующий раз адрес нового объекта перезаписывает значение, хранящееся в указателе pointer. На 5-й строке выполняется удаление объекта, созданного на последней итерации цикла. Однако первые 9 объектов остаются в динамической памяти, и одновременно в программе не остаётся переменных, которые бы хранили адреса этих объектов. Т.е. в 5-й строке невозможно ни получить доступ к первым 9 объектам, ни удалить их.

Чем опасны утечки памяти

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

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

Способы предотвращения

Существуют различные способы предотвращения утечек памяти.

Отказ от динамической памяти

Например, FORTRAN-77 полностью отказывается от применения механизмов динамического распределения памяти, что исключает подобные ошибки, но существенно ограничивает функциональность программ.

Владеющие указатели

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

Сборка мусора

Некоторые языки программирования (например, Оберон, Java, языки платформы .NET) предоставляют средства, позволяющие автоматически освобождать неиспользуемую память («сборщик мусора», англ. garbage collector). Сборщики мусора решают также и проблему циклических ссылок, но сборка мусора является ресурсоёмкой операцией. За использование подобных средств приходится расплачиваться быстродействием системы, и, главное, сборка мусора вносит неожиданные паузы в программу, что недопустимо в системах реального времени.

Сборка мусора была изобретена Джоном Маккарти примерно в 1959 году при разработке языка программирования Лисп, структура которого делает крайне затруднительным ручное управление памятью.

Перезапуск программы

В тех случаях, когда устранить утечки памяти не представляется возможным, например, при использовании кода, поставляемого в виде программных модулей и изготовленного сторонними разработчиками, применяют своеобразный способ игнорирования утечек. Код, подверженный утечкам, размещают в отдельной программе, а эту программу с нужной периодичностью перезапускают. Запуски и перезапуски программы выполняются внешней программой, которая также подаёт исходные данные и забирает результаты. Поскольку при завершении программы вся память, затребованная ей у операционной системы, возвращается операционной системе, такой метод не позволяет утечкам приобрести катастрофический характер.

Утечка других ресурсов

Также существует ошибка, именуемая утечкой дескрипторов: захваченные дескрипторы не возвращаются операционной системе.

Для борьбы с последствиями таких ошибок разработчики операционных систем вводят в них функциональность, позволяющую ограничивать объём памяти, количество дескрипторов и количество процессорного времени, доступного одному пользователю или конкретному процессу.

Обнаружение утечек

Для профессиональных языков программирования существуют специальные программы-профилировщики, позволяющие обнаружить в числе прочего и утечки памяти.

Для некоторых языков программирования существуют статические анализаторы кода, выявляющие элементы программы, потенциально способные приводить к логическим ошибкам, в том числе и к утечке памяти. Примитивный вариант такого анализатора реализует практически любой компилятор языка высокого уровня, в виде выдачи так называемых предупреждений (warnings) — сообщений о наличии в программе конструкций, формально не нарушающих синтаксис языка, но потенциально ошибочных.

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

См. также

Напишите отзыв о статье "Утечка памяти"

Ссылки

  • [ltearno.free.fr/dpus DPus]: A free tool that shows leaks under windows (buffers, GDI objects, registry keys, user handles, etc…
  • [jb2works.com/memoryleak/index.html Why doesn’t my application release the memory?] (Java FAQ)
  • [vld.codeplex.com/ Visual Leak Detector] for Visual Studio
  • [msdn.microsoft.com/library/en-us/vccore98/html/_core_detecting_a_memory_leak.asp Detecting a Memory Leak] (Using MFC Debugging Support)
  • [www.linuxgazette.com/issue81/kurup.html Is Your Memory Not What It Used To Be?]
  • [linuxjournal.com/article.php?sid=6556 Memory Leak Detection in C++]
  • [linuxjournal.com/article.php?sid=6059 Memory Leak Detection in Embedded Systems]
  • [www.ibm.com/developerworks/rational/library/05/0816_GuptaPalanki/ Java memory leaks — Catch me if you can]
  • [java.sun.com/developer/Books/javaprogramming/bitterjava/bitterjavach06.pdf Sample Chapter from Bitter Java]
  • [dev2dev.bea.com/pub/a/2005/06/memory_leaks.html Memory Leaks, Be Gone]
  • [www.macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html Memory Management in Objective-C]
  • [www.xakep.ru/post/41631/default.asp Борьба с утечками ресурсов в реальном времени]
  • [sourceforge.net/projects/fastmm Альтернативный менеджер памяти Delphi. Среди прочего ищет утечки памяти]

Отрывок, характеризующий Утечка памяти

– Я одно понимаю, что всё мерзко, мерзко и мерзко, – сказал князь Андрей и пошел в дом, где стоял главнокомандующий.
Пройдя мимо экипажа Кутузова, верховых замученных лошадей свиты и казаков, громко говоривших между собою, князь Андрей вошел в сени. Сам Кутузов, как сказали князю Андрею, находился в избе с князем Багратионом и Вейротером. Вейротер был австрийский генерал, заменивший убитого Шмита. В сенях маленький Козловский сидел на корточках перед писарем. Писарь на перевернутой кадушке, заворотив обшлага мундира, поспешно писал. Лицо Козловского было измученное – он, видно, тоже не спал ночь. Он взглянул на князя Андрея и даже не кивнул ему головой.
– Вторая линия… Написал? – продолжал он, диктуя писарю, – Киевский гренадерский, Подольский…
– Не поспеешь, ваше высокоблагородие, – отвечал писарь непочтительно и сердито, оглядываясь на Козловского.
Из за двери слышен был в это время оживленно недовольный голос Кутузова, перебиваемый другим, незнакомым голосом. По звуку этих голосов, по невниманию, с которым взглянул на него Козловский, по непочтительности измученного писаря, по тому, что писарь и Козловский сидели так близко от главнокомандующего на полу около кадушки,и по тому, что казаки, державшие лошадей, смеялись громко под окном дома, – по всему этому князь Андрей чувствовал, что должно было случиться что нибудь важное и несчастливое.
Князь Андрей настоятельно обратился к Козловскому с вопросами.
– Сейчас, князь, – сказал Козловский. – Диспозиция Багратиону.
– А капитуляция?
– Никакой нет; сделаны распоряжения к сражению.
Князь Андрей направился к двери, из за которой слышны были голоса. Но в то время, как он хотел отворить дверь, голоса в комнате замолкли, дверь сама отворилась, и Кутузов, с своим орлиным носом на пухлом лице, показался на пороге.
Князь Андрей стоял прямо против Кутузова; но по выражению единственного зрячего глаза главнокомандующего видно было, что мысль и забота так сильно занимали его, что как будто застилали ему зрение. Он прямо смотрел на лицо своего адъютанта и не узнавал его.
– Ну, что, кончил? – обратился он к Козловскому.
– Сию секунду, ваше высокопревосходительство.
Багратион, невысокий, с восточным типом твердого и неподвижного лица, сухой, еще не старый человек, вышел за главнокомандующим.
– Честь имею явиться, – повторил довольно громко князь Андрей, подавая конверт.
– А, из Вены? Хорошо. После, после!
Кутузов вышел с Багратионом на крыльцо.
– Ну, князь, прощай, – сказал он Багратиону. – Христос с тобой. Благословляю тебя на великий подвиг.
Лицо Кутузова неожиданно смягчилось, и слезы показались в его глазах. Он притянул к себе левою рукой Багратиона, а правой, на которой было кольцо, видимо привычным жестом перекрестил его и подставил ему пухлую щеку, вместо которой Багратион поцеловал его в шею.
– Христос с тобой! – повторил Кутузов и подошел к коляске. – Садись со мной, – сказал он Болконскому.
– Ваше высокопревосходительство, я желал бы быть полезен здесь. Позвольте мне остаться в отряде князя Багратиона.
– Садись, – сказал Кутузов и, заметив, что Болконский медлит, – мне хорошие офицеры самому нужны, самому нужны.
Они сели в коляску и молча проехали несколько минут.
– Еще впереди много, много всего будет, – сказал он со старческим выражением проницательности, как будто поняв всё, что делалось в душе Болконского. – Ежели из отряда его придет завтра одна десятая часть, я буду Бога благодарить, – прибавил Кутузов, как бы говоря сам с собой.
Князь Андрей взглянул на Кутузова, и ему невольно бросились в глаза, в полуаршине от него, чисто промытые сборки шрама на виске Кутузова, где измаильская пуля пронизала ему голову, и его вытекший глаз. «Да, он имеет право так спокойно говорить о погибели этих людей!» подумал Болконский.
– От этого я и прошу отправить меня в этот отряд, – сказал он.
Кутузов не ответил. Он, казалось, уж забыл о том, что было сказано им, и сидел задумавшись. Через пять минут, плавно раскачиваясь на мягких рессорах коляски, Кутузов обратился к князю Андрею. На лице его не было и следа волнения. Он с тонкою насмешливостью расспрашивал князя Андрея о подробностях его свидания с императором, об отзывах, слышанных при дворе о кремском деле, и о некоторых общих знакомых женщинах.


Кутузов чрез своего лазутчика получил 1 го ноября известие, ставившее командуемую им армию почти в безвыходное положение. Лазутчик доносил, что французы в огромных силах, перейдя венский мост, направились на путь сообщения Кутузова с войсками, шедшими из России. Ежели бы Кутузов решился оставаться в Кремсе, то полуторастатысячная армия Наполеона отрезала бы его от всех сообщений, окружила бы его сорокатысячную изнуренную армию, и он находился бы в положении Мака под Ульмом. Ежели бы Кутузов решился оставить дорогу, ведшую на сообщения с войсками из России, то он должен был вступить без дороги в неизвестные края Богемских
гор, защищаясь от превосходного силами неприятеля, и оставить всякую надежду на сообщение с Буксгевденом. Ежели бы Кутузов решился отступать по дороге из Кремса в Ольмюц на соединение с войсками из России, то он рисковал быть предупрежденным на этой дороге французами, перешедшими мост в Вене, и таким образом быть принужденным принять сражение на походе, со всеми тяжестями и обозами, и имея дело с неприятелем, втрое превосходившим его и окружавшим его с двух сторон.
Кутузов избрал этот последний выход.
Французы, как доносил лазутчик, перейдя мост в Вене, усиленным маршем шли на Цнайм, лежавший на пути отступления Кутузова, впереди его более чем на сто верст. Достигнуть Цнайма прежде французов – значило получить большую надежду на спасение армии; дать французам предупредить себя в Цнайме – значило наверное подвергнуть всю армию позору, подобному ульмскому, или общей гибели. Но предупредить французов со всею армией было невозможно. Дорога французов от Вены до Цнайма была короче и лучше, чем дорога русских от Кремса до Цнайма.