Я хочу знать о неуправляемых ресурсах. Кто-нибудь может дать мне основную идею?
Я хочу знать о неуправляемых ресурсах. Кто-нибудь может дать мне основную идею?
Ответы:
Под управляемыми ресурсами в основном подразумевается «управляемая память», которой управляет сборщик мусора. Если у вас больше нет ссылок на управляемый объект (который использует управляемую память), сборщик мусора (в конце концов) освободит эту память для вас.
Тогда неуправляемые ресурсы - это все, о чем сборщик мусора не знает. Например:
Обычно вы хотите освободить эти неуправляемые ресурсы, прежде чем потеряете все ссылки, которые у вас есть на объект, управляющий ими. Вы делаете это, вызывая Dispose
этот объект или (в C #) используя using
оператор, который будет обрабатывать вызов Dispose
для вас.
Если вы пренебрегаете Dispose
правильно своими неуправляемыми ресурсами, сборщик мусора в конечном итоге справится с вами, когда объект, содержащий этот ресурс, будет подвергнут сборке мусора (это «финализация»). Но поскольку сборщик мусора не знает о неуправляемых ресурсах, он не может сказать, насколько сильно он нуждается в их освобождении - поэтому ваша программа может работать плохо или полностью исчерпать ресурсы.
Если вы реализуете класс самостоятельно, который обрабатывает неуправляемые ресурсы, вы должны правильно Dispose
и Finalize
правильно его реализовать .
Dispose
или использовать using
.
IDisposable
. Если класс делает реализации IDisposable
, то вы должны избавиться от экземпляров этого класса с using
или , Dispose()
когда вы сделали с ними. Исходя из этого, ваше обратное утверждение верно: если класс реализует IDisposable
, то он, вероятно, содержит неуправляемые ресурсы внутри.
Некоторые пользователи ранжируют открытые файлы, соединения БД, выделенную память, битовые карты, файловые потоки и т. Д. Среди управляемых ресурсов, другие среди неуправляемых. Так они управляемые или неуправляемые?
Мое мнение таково, что ответ более сложный: когда вы открываете файл в .NET, вы, вероятно, используете какой-то встроенный класс .NET System.IO.File, FileStream или что-то еще. Поскольку это обычный класс .NET, им управляют. Но это обертка, которая внутри выполняет «грязную работу» (обменивается данными с операционной системой, используя библиотеки Win32, вызывая функции низкого уровня или даже инструкции ассемблера), которая действительно открывает файл. И это то, о чем .NET не знает, неуправляемый. Но вы, возможно, можете открыть файл самостоятельно, используя инструкции на ассемблере и обходя функции файла .NET. Тогда дескриптор и открытый файл являются неуправляемыми ресурсами.
То же самое с БД: если вы используете какую-то сборку БД, у вас есть классы, такие как DbConnection и т. Д., Они известны .NET и управляются. Но они оборачивают «грязную работу», которая неуправляема (выделять память на сервере, устанавливать с ней соединение, ...). Если вы не используете этот класс-обертку и самостоятельно открываете сетевой сокет и общаетесь со своей собственной странной базой данных, используя некоторые команды, это неуправляемо.
Этими классами-обертками (File, DbConnection и т. Д.) Управляют, но они внутри используют неуправляемые ресурсы так же, как вы, если вы не используете обертки и выполняете «грязную работу» самостоятельно. И поэтому эти обертки действительно реализуют шаблоны Dispose / Finalize. Они обязаны позволить программисту освобождать неуправляемые ресурсы, когда оболочка больше не нужна, и освобождать их, когда оболочка собирается мусором. Оболочка будет правильно собирать мусор сборщиком мусора, но неуправляемые ресурсы внутри будут собираться с использованием шаблона Dispose / Finalize.
Если вы не используете встроенные классы .NET или сторонние классы-обертки и открываете файлы с помощью некоторых инструкций ассемблера и т. Д. В вашем классе, эти открытые файлы неуправляемы, и вы ДОЛЖНЫ реализовать шаблон dispose / finalize. В противном случае произойдет утечка памяти, навсегда заблокированный ресурс и т. Д., Даже если вы больше не используете его (операция с файлом завершена) или даже после завершения работы приложения.
Но вы также несете ответственность за использование этих упаковщиков. Для тех, кто реализует dispose / finalize (вы узнаете их, что они реализуют IDisposable), внедрите также шаблон dispose / finalize и Dispose даже этих оболочек или дайте им сигнал освободить свои неуправляемые ресурсы. Если вы этого не сделаете, ресурсы будут освобождены через какое-то неопределенное время, но можно сразу же освободить их (немедленно закройте файл, не оставляя его открытым и заблокированным на случайные несколько минут / часов). Таким образом, в методе Dispose вашего класса вы вызываете методы Dispose всех используемых вами оболочек.
unmanaged vs managed resources
«Неуправляемый ресурс» - это не вещь, а ответственность. Если объект владеет неуправляемым ресурсом, это означает, что (1) некоторый объект за его пределами был обработан таким образом, что может вызвать проблемы, если он не очищен, и (2) объект обладает информацией, необходимой для выполнения такой очистки, и несет ответственность для этого.
Хотя многие типы неуправляемых ресурсов очень сильно связаны с объектами операционной системы различного типа (файлами, дескрипторами GDI, выделенными блоками памяти и т. Д.), Не существует единого типа объектов, который совместно используется всеми ними, кроме ответственности очистки. Как правило, если какой-либо объект несет ответственность за выполнение очистки, у него будет метод Dispose, который инструктирует ему выполнять всю очистку, за которую он отвечает.
В некоторых случаях объекты допускают возможность того, что они могут быть оставлены без предварительного вызова Dispose. GC позволяет объектам запрашивать уведомление о том, что они были оставлены (путем вызова процедуры, называемой Finalize), и объекты могут использовать это уведомление для выполнения очистки самостоятельно.
Такие термины, как «управляемый ресурс» и «неуправляемый ресурс», к сожалению, используются разными людьми для обозначения разных вещей; Откровенно говоря, более полезно думать с точки зрения объектов как об отсутствии ответственности за очистку, об ответственности за очистку, о которой будет заботиться только при вызове Dispose, или об ответственности за очистку, о которой следует заботиться через Dispose, но которая может также позаботиться о Finalize.
Основное различие между управляемым и неуправляемым ресурсом заключается в том, что сборщик мусора знает обо всех управляемых ресурсах, и в какой-то момент времени GC обнаружит и очистит всю память и ресурсы, связанные с управляемым объектом. GC не знает о неуправляемых ресурсах, таких как файлы, потоки и дескрипторы, поэтому, если вы не очистите их явно в своем коде, то вы получите утечки памяти и заблокированные ресурсы.
Украденный отсюда , не стесняйтесь читать весь пост.
Любой ресурс, для которого выделена память в управляемой куче .NET, является управляемым ресурсом. CLR полностью осведомлена об этом виде памяти и сделает все, чтобы она не потеряла сознание. Все остальное неуправляемо. Например, взаимодействие с COM может создать объекты в области памяти процесса, но CLR об этом не позаботится. В этом случае управляемый объект, который выполняет вызовы через управляемую границу, должен нести ответственность за все, что находится за его пределами.
Давайте сначала разберемся, как выполнялись программы VB6 или C ++ (не Dotnet-приложения). Мы знаем, что компьютеры понимают только код машинного уровня. Код машинного уровня также называется собственным или двоичным кодом. Таким образом, когда мы выполняем программу на VB6 или C ++, соответствующий языковой компилятор компилирует исходный код соответствующего языка в собственный код, который затем может быть понят базовой операционной системой и оборудованием.
Собственный код (неуправляемый код) является специфическим (нативным) для операционной системы, в которой он генерируется. Если вы возьмете этот скомпилированный нативный код и попытаетесь запустить его в другой операционной системе, он потерпит неудачу. Таким образом, проблема с этим стилем выполнения программы заключается в том, что она не переносима с одной платформы на другую.
Давайте теперь разберемся, как работает программа .Net. Используя dotnet, мы можем создавать различные типы приложений. Некоторые из распространенных типов приложений .NET включают веб-приложения, приложения для Windows, консольные и мобильные приложения. Независимо от типа приложения, при запуске любого приложения .NET происходит следующее
Приложение .NET компилируется в промежуточный язык (IL). IL также упоминается как общий промежуточный язык (CIL) и промежуточный язык Microsoft (MSIL). Приложения .NET и не .NET генерируют сборку. Сборки имеют расширение .DLL или .EXE. Например, если вы компилируете Windows или консольное приложение, вы получаете .EXE, тогда как, когда мы компилируем веб-проект или проект библиотеки классов, мы получаем .DLL. Разница между сборкой .NET и NON .NET заключается в том, что сборка DOTNET выполняется в формате промежуточного языка, а сборка NON DOTNET - в формате собственного кода.
Приложения без DOTNET могут работать непосредственно поверх операционной системы, тогда как приложения DOTNET работают поверх виртуальной среды, называемой Common Language Runtime (CLR). CLR содержит компонент под названием Just In-Time Compiler (JIT), который преобразует промежуточный язык в нативный код, понятный базовой операционной системе.
Итак, в .NET выполнение приложения состоит из 2 шагов: 1. Компилятор языка, компилирует исходный код в промежуточный язык (IL) 2. Компилятор JIT в CLR преобразует IL в собственный код, который затем можно запустить в базовой операционной системе. ,
Поскольку сборка .NET имеет формат Intermedaite Language, а не собственный код, сборки .NET переносимы на любую платформу, если целевая платформа имеет Common Language Runtime (CLR). CLR целевой платформы преобразует язык Intermedaite в собственный код, понятный базовой операционной системе. Промежуточный язык также называется управляемым кодом. Это потому, что CLR управляет кодом, который выполняется внутри него. Например, в программе VB6 разработчик отвечает за освобождение памяти, используемой объектом. Если программист забывает освободить память, мы можем столкнуться с трудностями при обнаружении исключений из памяти. С другой стороны, программисту .NET не нужно беспокоиться о перераспределении памяти, используемой объектом. CLR обеспечивает автоматическое управление памятью, также известное как сбор мусора. Отдельно, от сборки мусора, есть несколько других преимуществ, предоставляемых CLR, которые мы обсудим на следующем занятии. Поскольку CLR управляет и исполняет промежуточный язык, он (IL) также называется управляемым кодом.
.NET поддерживает разные языки программирования, такие как C #, VB, J # и C ++. C #, VB и J # могут генерировать только управляемый код (IL), тогда как C ++ может генерировать как управляемый код (IL), так и неуправляемый код (собственный код).
Собственный код нигде не хранится постоянно, после того, как мы закрываем программу, нативный код выбрасывается. Когда мы снова запускаем программу, собственный код генерируется снова.
Программа .NET похожа на выполнение Java-программы. В Java у нас есть байт-коды и JVM (виртуальная машина Java), где, как и в .NET, у нас есть Intermediate Language и CLR (Common Language Runtime).
Это обеспечивается по этой ссылке - он отличный репетитор. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html