Анатомия «Memory Leak»

голоса
159

В .NET перспективе:

  • Что такое утечка памяти ?
  • Как вы можете определить, является ли утечек приложений? Каковы последствия?
  • Как вы можете предотвратить утечку памяти?
  • Если ваше приложение имеет утечку памяти, она исчезнет, ​​когда процесс выходит или убит? Или утечка памяти в приложении влияет на другие процессы в системе даже после завершения процесса?
  • А что неуправляемый код доступен через COM Interop и / или P / Invoke?
Задан 01/08/2008 в 16:12
источник пользователем
На других языках...                            


15 ответов

голоса
106

Лучшее объяснение , которое я видел в главе 7 свободных Основы программирования электронной книги .

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

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

Понимание .NET модели памяти «s это лучший способ избежать его. В частности, понимание того, как работает сборщик мусора и как ссылки на работу - опять же , я отсылаю вас к главе 7 электронной книги. Кроме того , следует помнить о распространенных ошибках, вероятно, наиболее распространенным из которых является событием. Если объект зарегистрирован событие на объект B , то объект A будет придерживаться вокруг , пока объект B не исчезнет , потому что B содержит ссылку на . Решение состоит в том, чтобы отменить ваши события , когда вы закончите.

Конечно, хороший профиль память позволит вам увидеть ваши графики объектов и исследовать вложенности / реферирование ваших объектов , чтобы увидеть , где ссылки идут от и корневой объект отвечает ( красный ворот муравьи профиль , JetBrains dotMemory, memprofiler действительно хорошо выбор, или вы можете использовать только текст WinDbg и SOS , но я бы настоятельно рекомендовал коммерческим / визуальный продукт , если вы не настоящий гуру).

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

Ответил 01/08/2008 в 16:28
источник пользователем

голоса
32

Строго говоря, утечка памяти потребляет память, которая не является «больше не используется» программой.

«Нет больше используется» не имеет более одного значения, это может означать «больше нет ссылок на него», то есть, полностью невозвратными, или это может означать, ссылки, извлекаемые, неиспользованные , но программа сохраняет ссылки в любом случае. Только позже относится к .Net для прекрасно управляемых объектов . Однако, не все классы совершенны и в какой - то момент основная неуправляемый реализация может привести к утечке ресурсов постоянно для этого процесса.

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

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

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

Ответил 01/08/2008 в 18:52
источник пользователем

голоса
28

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

Как понять, есть ли ваши утечки приложений

Один интересный способ открыть Perfmon и добавить следы на # байт во всех кучах и # Gen 2 коллекциях , в каждом конкретном случае , глядя только на вашем процессе. Если осуществлять определенную функцию вызывает общее количество байтов увеличиваться, и что память остается выделенным после следующей коллекции Gen 2, можно сказать , что функция утечки памяти.

Как предотвратить

Другие хорошие мнения были даны. Я бы только добавить , что , возможно, наиболее часто упускается из виду причиной утечек памяти .NET является добавление обработчиков событий к объектам , не удаляя их. Обработчик событий прилагается к объекту является формой ссылки на этот объект, так будет препятствовать сбору даже после того, как все остальные ссылки уже ушли. Всегда помните , чтобы отделить обработчиков событий (используя -=синтаксис в C #).

идти ли утечка прочь, когда процесс завершает работу, а как насчет COM Interop?

Когда ваш процесс завершается, все отображенные на память в его адресное пространство будет утилизирован ОС, в том числе любые COM объекты подается из библиотек DLL. Сравнительно редко, СОМ-объекты могут обслуживаться из отдельных процессов. В этом случае, когда ваш процесс выходит, вы можете по-прежнему нести ответственность за память, выделенную в любом COM серверных процессов, которые вы использовали.

Ответил 15/08/2008 в 17:11
источник пользователем

голоса
18

Если вам нужно диагностировать утечка памяти в .NET, проверьте эти ссылки:

http://msdn.microsoft.com/en-us/magazine/cc163833.aspx

http://msdn.microsoft.com/en-us/magazine/cc164138.aspx

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

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

http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en

Ответил 15/08/2008 в 00:16
источник пользователем

голоса
18

Я хотел бы определить утечки памяти как объект не освобождает всю память, выделенную после его завершения. Я нашел, что это может произойти в вашем приложении, если вы используете Windows API и COM (т.е. неуправляемый код, который содержит ошибку в нем, либо не удалось правильно), в рамках и в компонентах третьих лиц. Кроме того, я нашел не клининг после использования определенных объектов, как ручки могут вызвать проблемы.

Я лично пострадал Из исключений памяти , которые могут быть вызваны , но не являются исключительными для утечки памяти в Dot Net приложений. (ООМ может также исходить от пиннинга см пиннинга Artical ). Если вы не получаете ошибки ООМ или должны подтвердить , что это утечка памяти , заставляя его то единственный путь к профилю вашего приложения.

Я хотел бы также попытаться обеспечить следующее:

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

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

в) Если вы используете неуправляемый код / ​​Windows API, что эти рассматриваются правильно после. (Некоторые из них очистить методы, чтобы освободить ресурсы)

Надеюсь это поможет.

Ответил 01/08/2008 в 18:57
источник пользователем

голоса
15

Использование CLR Profiler от Microsoft http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en это отличный способ , чтобы определить , какие объекты держат память, то , что выполнение приводит поток к созданию этих объектов, а также мониторинг , какие объекты жить там , где в куче (фрагментация, LOH и т.д.).

Ответил 16/08/2008 в 20:54
источник пользователем

голоса
14

Лучшее объяснение того , как работает сборщик мусора в Джеффа Richters CLR с помощью C # книги (гл. 20). Читая это дает большое заземление для понимания того, как объекты сохраняются.

Одной из наиболее распространенных причин укоренения объекты случайно является подключение события outisde класса. Если подключить внешнее событие

например

SomeExternalClass.Changed += new EventHandler(HandleIt);

и забыть отцепить к нему, когда вы располагаете, то SomeExternalClass имеет реф в своем классе.

Как уже упоминалось выше, профайлер памяти SciTech это отлично показывает вам корни объектов , которые вы подозреваете, протекающие.

Но есть и очень быстрый способ, чтобы проверить конкретный тип просто использовать WnDBG (вы даже можете использовать это в ближайшем окне VS.NET, прикрепив):

.loadby sos mscorwks
!dumpheap -stat -type <TypeName>

Теперь сделайте то , что вы думаете , будет распоряжаться объектами этого типа (например , закрыть окно). Это удобно здесь , чтобы иметь кнопку отладки где - то , что будет работать System.GC.Collect()несколько раз.

Затем запустите !dumpheap -stat -type <TypeName>снова. Если номер не пошел или не пошел вниз столько , сколько вы ожидаете, то у вас есть основания для дальнейшего расследования. (Я получил этот совет от семинара дается Ingo Rammer ).

Ответил 27/08/2008 в 15:12
источник пользователем

голоса
14

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

Ответил 01/08/2008 в 16:19
источник пользователем

голоса
10

Почему люди думают, что утечка памяти в .NET не то же самое, как и любой другой утечка?

Утечка памяти при подключении к ресурсу и не позволить ей идти. Вы можете сделать это как в управляемом и неуправляемом в кодировании.

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

Полагая, что GC и другая магия очистят ваш беспорядок является коротким путем к утечкам памяти, и будет трудно найти позже.

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

В .NET с другой стороны, многие люди думают, что GC будет убирать все. Ну, это делает некоторые для вас, но вы должны убедиться, что это так. .NET делает обернуть много вещей, так что вы не всегда знаете, если вы имеете дело с управляемым или неуправляемым ресурсом, и вы должны убедиться, что то, что вы имеете дело с. Обработка шрифтов, GDI ресурсов, Active Directory, базы данных и т.д., как правило, вещи, которые нужно обратить внимание.

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

Я вижу много людей имеют это, хотя, и я действительно надеюсь, что это закончится. Вы не можете попросить пользователя прекратить ваше приложение, чтобы очистить ваш беспорядок! Посмотрите на браузер, который может быть IE, FF и т.д., а затем открыть, скажем, Google Reader, пусть останется на несколько дней, и посмотреть на то, что происходит.

Если вы затем открыть другую вкладку в браузере, прибой на какой-либо сайт, а затем закрыть вкладку, размещенного на другую страницу, которая сделала утечку браузера, вы думаете, что браузер будет освободить память? Не так с IE. На моем компьютере IE легко съесть 1 контрклин памяти в короткий промежуток времени (около 3-4 дней), если я использую Google Reader. Некоторые newspages еще хуже.

Ответил 01/09/2008 в 13:19
источник пользователем

голоса
10

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

Абсолютно. Кроме того, не используя метод .Dispose () на одноразовых предметов при необходимости может вызвать утечку Mem. Самый простой способ сделать это с помощью блока, поскольку он автоматически выполняет .Dispose () в конце:

StreamReader sr;
using(sr = new StreamReader("somefile.txt"))
{
    //do some stuff
}

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

Ответил 05/08/2008 в 23:47
источник пользователем

голоса
9

Все утечки памяти разрешаются путем завершения программы.

Течь достаточно памяти и операционная система может решить, чтобы решить эту проблему от вашего имени.

Ответил 04/08/2008 в 15:09
источник пользователем

голоса
9

Я согласен с Бернардом, как в .net, что будет утечка мем.

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

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

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

Ответил 01/08/2008 в 16:23
источник пользователем

голоса
7

Кроме того, имейте в виду, что .NET имеет две кучки, один из которых большой объект кучи. Я считаю, что объекты примерно 85k или больше ставятся на эту кучу. Эта куча имеет различные правила жизни, чем обычная куча.

Если вы создаете большие структуры памяти (словарь или Лист) было бы разумно, чтобы идти Lookup, что точные правила.

Насколько вернув память о прекращении процесса, если ваш использовать Win98 или эквиваленты, все отпускается обратно в ОС по окончании. Исключением являются только вещи, которые открываются кросс-процесс, а другой процесс до сих пор ресурс открытым.

COM объекты могут быть сложно Тхо. Если вы всегда использовать IDisposeшаблон, вы будете в безопасности. Но я перебежать несколько сборок взаимодействия , которые реализуют IDispose. Ключевым моментом здесь является вызов , Marshal.ReleaseCOMObjectкогда вы сделали с ним. COM - объекты до сих пор используют стандартный COM - подсчет ссылок.

Ответил 07/08/2008 в 14:17
источник пользователем

голоса
6

Я нашел в системе .Net Memory Profiler очень хорошо помогает при обнаружении утечки памяти в .NET. Это не бесплатно , как Microsoft CLR Profiler, но быстрее и до точки , на мой взгляд.

Ответил 20/08/2008 в 19:39
источник пользователем

голоса
1

Одно определение: Невозможно освободить недостижимую память, которая больше не может быть выделена для нового процесса во время выполнения процесса выделения. Это в большинстве случаев может быть вылечено с использованием методов ГХ или обнаружение с помощью автоматизированных инструментов.

Для получения дополнительной информации, пожалуйста , посетите http://all-about-java-and-weblogic-server.blogspot.in/2014/01/what-is-memory-leak-in-java.html .

Ответил 27/08/2014 в 16:22
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more