Вы пытались решить проблему с клейкой лентой?
Попробуйте определить, когда возникают ошибки, и исправьте их короткими операторами if, это не очень, но для некоторых проблем это единственное решение, и это один из них .
if( (n * 0.1) < 100.0 ) { return n * 0.1 - 0.000000000000001 ;}
else { return n * 0.1 + 0.000000000000001 ;}
У меня была такая же проблема в проекте научной симуляции в c #, и я могу сказать вам, что если вы проигнорируете эффект бабочки, он превратится в большого толстого дракона и укусит вас в a **
Существует 3 способа управления памятью: -
GC работает только для управляемых ресурсов, поэтому .NET предоставляет Dispose и Finalize для выпуска неуправляемых ресурсов, таких как поток, подключение к базе данных, COM-объекты и т. д. ..
Dispose следует вызывать явно для типов, которые реализуют IDisposable.
Программист должен вызывать это либо с помощью Dispose (), либо с помощью функции Create
Используйте GC.SuppressFinalize (this), чтобы предотвратить вызов Finalizer, если вы уже использовали dispose ()
Он называется неявным после того, как объект имеет право на очистку, финализатор для объектов вызывается последовательно по потоку финализатора.
Недостатком реализации финализатора является то, что его восстановление памяти задерживается, поскольку финализатор для такого класса / типов должен быть вызван предварительной очисткой,
Использование GC.Collect () не обязательно устанавливает GC для сбора, GC все еще может переопределять и запускать, когда захочет.
также GC.Collect () будет запускать трассировочную часть сбора мусора и добавлять элементы в очередь финализатора, но не вызывать финализаторы для типов, которые обрабатываются другим потоком .
Используйте WaitForPendingFinalizers, если вы хотите убедиться, что все финализаторы были вызваны после вызова GC.Collect ()
[Просто хотелось добавить дальше в процесс «Внутренние процессы завершения»]
Итак, вы создаете объект, и когда объект собирается, следует вызвать метод Finalize
объекта. Но есть еще кое-что для завершения, чем это очень простое предположение.
КРАТКИЕ КОНЦЕПЦИИ ::
Finalize
, там память немедленно исправляется, если, конечно, , они больше не выполняются с помощью кода приложения Finalize
, Концепция / Реализация Application Roots
, Finalization Queue
, Freacheable Queue
предшествует их исправлению. Предположим: классы / объекты 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
методы и указатели на эти объекты, добавляются в очередь завершения . [/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 [/g19]
Существует специальный поток времени выполнения, посвященный вызовам методов Finalize. Когда freachable queue пуст (как правило, это так), этот поток засыпает. Но когда появляются записи, этот поток просыпается, удаляет каждую запись из очереди и вызывает метод Finalize каждого объекта. Сборщик мусора сжимает возвращаемую память, и специальный поток времени запуска освобождает свободную очередь, выполняя метод Finalize
каждого объекта. Итак, вот наконец, когда ваш метод Finalize выполняется
В следующий раз, когда вызывается сборщик мусора (2-я сборка), он видит, что финализированные объекты действительно мусор, так как корни приложения не используются, t указывает на него, а [freelable queue] больше не указывает на него (это тоже ПУСТОЙ), поэтому память для объектов (E, I, J) просто восстанавливается из диаграммы Heap.See ниже и сравнивается это с рисунком чуть выше [/g20]
. Важно понять, что два GC необходимы для восстановления памяти, используемой объектами, требующими завершения. В действительности, требуется больше двух сборных кабин, поскольку эти объекты могут быть переданы старшему поколению
ПРИМЕЧАНИЕ :: . Распределенная очередь считается корнем, как и глобальная и статические переменные являются корнями. Поэтому, если объект находится в freachable queue, тогда объект доступен и не является мусором.
Как последнее примечание, помните, что приложение для отладки - это одно, а Garbage Collection - это еще одна вещь и работает по-разному. Пока вы не можете ЧУВСТВИТЬ сборку мусора, просто отлаживая приложения, и если вы хотите исследовать память, то получите здесь.