Почему этот код C # отмечает утечку? [Дубликат]

Вы пытались решить проблему с клейкой лентой?

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

 if( (n * 0.1) < 100.0 ) { return n * 0.1 - 0.000000000000001 ;}
                    else { return n * 0.1 + 0.000000000000001 ;}    

У меня была такая же проблема в проекте научной симуляции в c #, и я могу сказать вам, что если вы проигнорируете эффект бабочки, он превратится в большого толстого дракона и укусит вас в a **

142
задан Peter Mortensen 6 February 2016 в 22:38
поделиться

3 ответа

311
ответ дан Hans Passant 1 September 2018 в 03:31
поделиться

Существует 3 способа управления памятью: -

GC работает только для управляемых ресурсов, поэтому .NET предоставляет Dispose и Finalize для выпуска неуправляемых ресурсов, таких как поток, подключение к базе данных, COM-объекты и т. д. ..

1) Dispose

Dispose следует вызывать явно для типов, которые реализуют IDisposable.

Программист должен вызывать это либо с помощью Dispose (), либо с помощью функции Create

Используйте GC.SuppressFinalize (this), чтобы предотвратить вызов Finalizer, если вы уже использовали dispose ()

2) Finalize или Distructor

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

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

3) GC.Collect ()

Использование GC.Collect () не обязательно устанавливает GC для сбора, GC все еще может переопределять и запускать, когда захочет.

также GC.Collect () будет запускать трассировочную часть сбора мусора и добавлять элементы в очередь финализатора, но не вызывать финализаторы для типов, которые обрабатываются другим потоком .

Используйте WaitForPendingFinalizers, если вы хотите убедиться, что все финализаторы были вызваны после вызова GC.Collect ()

1
ответ дан Pankaj Singh 1 September 2018 в 03:31
поделиться

[Просто хотелось добавить дальше в процесс «Внутренние процессы завершения»]

Итак, вы создаете объект, и когда объект собирается, следует вызвать метод Finalize объекта. Но есть еще кое-что для завершения, чем это очень простое предположение.

КРАТКИЕ КОНЦЕПЦИИ ::

  1. Объекты НЕ реализуют методы Finalize, там память немедленно исправляется, если, конечно, , они больше не выполняются с помощью кода приложения
  2. Объекты, реализующие метод Finalize, Концепция / Реализация Application Roots, Finalization Queue, Freacheable Queue предшествует их исправлению.
  3. Любой объект считается мусором, если он не доступен для кода приложения

Предположим: классы / объекты A, B, D, G, H НЕ реализуют Finalize Метод и C, E, F, I, J реализуют метод Finalize.

Когда приложение создает новый объект, новый оператор выделяет память из кучи. Если тип объекта содержит метод Finalize, указатель на объект помещается в очередь финализации . , поэтому указатели на объекты C, E, F, I, J добавляются в очередь финализации. Очередь финализации - это внутренняя структура данных, управляемая сборщиком мусора. Каждая запись в очереди указывает на объект, который должен иметь метод Finalize, вызываемый до того, как память объекта может быть восстановлена. На рисунке ниже показана куча, содержащая несколько объектов. Некоторые из этих объектов доступны из корней приложения , а некоторые нет. Когда объекты C, E, F, I и J были созданы, инфраструктура .Net обнаруживает, что эти объекты имеют Finalize методы и указатели на эти объекты, добавляются в очередь завершения . enter image description here [/g18]

Когда GC происходит (первая коллекция), объекты B, E, G, H, I и J определяются как мусор. Поскольку A, C, D, F по-прежнему сохраняются в коде приложения, изображенной стрелками из желтой коробки выше.

Сборщик мусора сканирует очередь завершения ища указатели на эти объекты. Когда указатель найден, указатель удаляется из очереди финализации и добавляется в свободную очередь («F-достижимая»). freachable queue - это другая внутренняя структура данных, управляемая сборщиком мусора. Каждый указатель в freachable queue идентифицирует объект, который готов к вызову метода Finalize.

После коллекции (1-я коллекция) управляемая куча выглядит примерно так, как ниже. Объяснение, приведенное ниже: 1.) Память, занятая объектами B, G и H, была немедленно исправлена, потому что у этих объектов не был метод finalize, который нужно было называть .

2.) Однако память, занятая объектами E, I и J, не могла быть восстановлена, потому что их метод Finalize еще не был вызван. Вызов метода Finalize выполняется с помощью

3.) A, C, D, F по-прежнему доступны в виде кода приложения, изображенного стрелками из желтой коробки выше, поэтому они НЕ будут собраны в любом case enter image description here [/g19]

Существует специальный поток времени выполнения, посвященный вызовам методов Finalize. Когда freachable queue пуст (как правило, это так), этот поток засыпает. Но когда появляются записи, этот поток просыпается, удаляет каждую запись из очереди и вызывает метод Finalize каждого объекта. Сборщик мусора сжимает возвращаемую память, и специальный поток времени запуска освобождает свободную очередь, выполняя метод Finalize каждого объекта. Итак, вот наконец, когда ваш метод Finalize выполняется

В следующий раз, когда вызывается сборщик мусора (2-я сборка), он видит, что финализированные объекты действительно мусор, так как корни приложения не используются, t указывает на него, а [freelable queue] больше не указывает на него (это тоже ПУСТОЙ), поэтому память для объектов (E, I, J) просто восстанавливается из диаграммы Heap.See ниже и сравнивается это с рисунком чуть выше enter image description here [/g20]

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

ПРИМЕЧАНИЕ :: . Распределенная очередь считается корнем, как и глобальная и статические переменные являются корнями. Поэтому, если объект находится в freachable queue, тогда объект доступен и не является мусором.

Как последнее примечание, помните, что приложение для отладки - это одно, а Garbage Collection - это еще одна вещь и работает по-разному. Пока вы не можете ЧУВСТВИТЬ сборку мусора, просто отлаживая приложения, и если вы хотите исследовать память, то получите здесь.

28
ответ дан R.C 1 September 2018 в 03:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: