Що саме є некерованими ресурсами?


159

Я хочу знати про некеровані ресурси. Може хто-небудь, будь ласка, дайте мені основну думку?


Також дивіться цю сторінку, яка дає фантастичне пояснення та схему правильного використання IDisposable та як врахувати некеровані ресурси: stackoverflow.com/questions/538060/…
Кайл Баран,

Відповіді:


177

Керовані ресурси в основному означають "керовану пам'ять", якою керує сміттєзбірник. Коли у вас більше немає посилань на керований об’єкт (який використовує керовану пам'ять), збирач сміття (зрештою) звільнить цю пам'ять для вас.

Некеровані ресурси - це все, про що смітник не знає. Наприклад:

  • Відкрити файли
  • Відкрийте мережеві з'єднання
  • Некерована пам'ять
  • У XNA: вершинні буфери, буфери індексів, текстури тощо.

Зазвичай ви хочете звільнити ці некеровані ресурси, перш ніж ви втратите всі посилання на об'єкт, яким керує ними. Ви робите це, зателефонувавши Disposeна цей об’єкт або (у C #), використовуючи usingоператор, який буде обробляти дзвінки Disposeза вас.

Якщо ви знехтуєте Disposeсвоїми некерованими ресурсами правильно, збирач сміття врешті обробляє це за вас, коли об’єкт, що містить цей ресурс, зібраний сміття (це "доопрацювання"). Але оскільки збирач сміття не знає про некеровані ресурси, він не може сказати, наскільки погано потрібно їх звільнити - тому для вашої програми можливо погана робота або вичерпання ресурсів цілком.

Якщо ви самостійно впроваджуєте клас, який обробляє некеровані ресурси, то саме вам належить реалізувати Disposeта Finalizeправильно.


7
Під якою категорією підключається відкрите підключення до бази даних? Керований / Некерований?
Девіпрасад Дас

8
+1 Інші відповіді пропускають важливий момент, який ви викликаєте Dispose на керованому об'єкті, який внутрішньо обробляє звільнення від керованого ним ресурсу (наприклад, обробка файлів, GDI + bitmap, ...) і що якщо ви отримуєте доступ безпосередньо до керованих ресурсів ( PInvoke тощо), вам потрібно впоратися з цим.
Ян Мерсер

2
@Dev: Некерований - оскільки GC не знає про це (якщо припустити, що ви не використовуєте певну гіпотетичну базу даних в керованій пам'яті). Але об'єкт з'єднання сам не може тримати некерований ресурс. Імовірно, для підключення до бази даних десь використовується відкритий файл або мережеве з'єднання, але можливо, що інший об'єкт (крім об'єкта з'єднання) обробляє цей некерований ресурс (можливо, ваша бібліотека бази даних кешує з'єднання). Перевірте документацію і подивіться, де вона просить вас зателефонувати Disposeчи скористатися using.
Ендрю Рассел

11
У мене є основний коментар / питання щодо цього, чи можу я пов’язати об'єкт як керований / некерований лише за типом, наприклад, рядок керується, DataSet не керується (саме тому він має метод Dispose ()) , Підключення до бази даних не керуються (тому що вони розпоряджаються) і т. Д. Тож припущення, якщо в ньому є метод "Dispose ()", то це не керується? На додаток до цього, яким буде об’єкт XmlDocument? Спасибі
подарунки

15
@ganders Це хороше правило. Хоча майте на увазі, що всі екземпляри класу C # - це керовані об'єкти. Якщо екземпляр класу міг би містити некеровані ресурси, то цей клас повинен реалізувати IDisposable. Якщо клас робить реалізації IDisposable, то ви повинні позбавитися від реалізації відповідного класу з usingабо , Dispose()коли ви зробили з ними. Виходячи з цього, ваше зворотне твердження: Якщо клас реалізує IDisposable, то він, ймовірно, містить внутрішні керовані ресурси.
Ендрю Рассел

56

Деякі користувачі класифікують відкриті файли, db-з'єднання, виділену пам’ять, растрові карти, потоки файлів тощо серед керованих ресурсів, інші - серед некерованих. Так вони управляються чи не керуються?

На мою думку, відповідь складніша: Коли ви відкриваєте файл у .NET, ви, ймовірно, використовуєте якийсь вбудований .NET-клас System.IO.File, FileStream або щось інше. Оскільки це нормальний .NET клас, ним керується. Але це обгортка, яка всередині виконує "брудну роботу" (спілкується з операційною системою, використовуючи dll Win32, викликаючи функції низького рівня або навіть інструкції асемблера), які дійсно відкривають файл. І це те, про що .NET не знає, некерований. Але, можливо, ви можете відкрити файл самостійно, скориставшись інструкціями асемблера та обійшовши функції файлу .NET. Тоді ручка та відкритий файл - некеровані ресурси.

Те ж саме з БД: Якщо ви використовуєте деяку збірку БД, у вас є такі класи, як DbConnection і т. Д., Вони відомі .NET і керуються ними. Але вони завершують «брудну роботу», яка не управляється (виділяйте пам’ять на сервері, встановлюйте зв’язок з нею, ...). Якщо ви не використовуєте цей клас обгортки і не відкриваєте якийсь мережевий сокет самостійно і спілкуєтесь із власною дивною базою даних за допомогою деяких команд, це не управляється.

Цими класами обгортки (File, DbConnection тощо) керують, але вони всередині використовують некеровані ресурси так само, як і ви, якщо ви не використовуєте обгортки і виконайте "брудну роботу" самостійно. Отже, ці обгортки дійсно реалізують шаблони утилізації / завершення. Їх відповідальність полягає в тому, щоб дозволити програмісту випускати некеровані ресурси, коли обгортка більше не потрібна, і випускати їх, коли обгортка збирається сміттям. Обгортка буде правильно сміттям, зібраним сміттєзбірником, але некеровані ресурси всередині збиратимуться за допомогою шаблону "Утилізувати / Фіналізувати".

Якщо ви не використовуєте вбудовані класи .NET або сторонні обгортки та відкриті файли за допомогою інструкцій асемблера тощо у вашому класі, ці відкриті файли не керуються, і ви ОБОВ'ЯЗКОВО реалізуєте шаблон розпорядження / доопрацювання. Якщо цього не зробити, випаде пам'ять, назавжди заблокований ресурс тощо, навіть коли ви більше не користуєтесь ним (файлова робота завершена) або навіть після завершення роботи програми.

Але ваша відповідальність також полягає у використанні цих обгортків. Для тих, хто реалізує розпорядження / доопрацювання (ви визнаєте їх, що вони реалізують IDisposable), реалізуйте також свою схему розпорядження / доопрацювання та розмістіть навіть ці обгортки або подайте їм сигнал для звільнення своїх некерованих ресурсів. Якщо ви цього не зробите, ресурси будуть випущені через деякий невизначений час, але його можна негайно випустити (негайно закрийте файл, не залишаючи його відкритим і заблокованим випадковим чином декілька хвилин / годин). Тож у своєму розпорядженні методом розпорядження класу ви називаєте методи викидання всіх використаних обгортків.


1
Хороший на додаткову ясністьunmanaged vs managed resources
тепер той, хто не повинен бути названий.

THX для вашої відповіді. на яких класах рекомендується насправді викликати Dispose?
BKSpurgeon

2
Це просто. Для кожного класу, який ви використовуєте, ви повинні перевірити, чи реалізований він інтерфейс IDisposable. Якщо так, то, якщо ви використовуєте такий клас одним методом (наприклад: відкриття файлу, зберігання тексту, закриття файлу), ви можете використовувати цю схему, використовуючи шаблон () {}, який викликає розпорядження для вас автоматично. Якщо ви використовуєте такий клас у більшій кількості методів (наприклад, ваш клас містить файл, в конструкторі він відкриває файл, потім декілька методів додають деякі журнали ...), тоді ви повинні реалізувати інтерфейс, що не використовується, для вашого класу, реалізувати шаблон розпорядження / завершення і належним чином розпоряджатися об’єктом цього класу.
Мартас

1
"... якийсь вбудований .NET-клас System.IO.File, FileStream або щось інше. Оскільки це звичайний .NET-клас, ним керується." З повагою це неправильно і вводить в оману. Вони не управляються . Якщо ними керували, ви могли б виділити ці класи і сподіватися, що сміттєзбірник повністю обробляє розподіл усіх ресурсів детерміновано. Однак це призведе до того, що ручки файлів і некеровані ресурси будуть заблоковані та утримуються набагато довше, ніж це необхідно, оскільки збирач сміття не буде розміщувати клас і не доопрацьовувати його потенційно дуже довго.
AaronLS

1
@AaronLS у своєму коментарі ви говорили про "FileStream", називаючи це як некерований, але його немає, хоча внутрішньо він використовує некеровані ресурси для виконання своєї роботи. У керованому світі Microsoft заховала від вас багато некерованих речей, реалізуючи розпоряджатися візерунком. Керований код не означає, що він не використовує некеровані ресурси. Однак Microsoft зробила хорошу роботу з впровадженням IDisposable для цих типів об’єктів. Про це свідчить той факт, що він реалізує IDisposable. Стосовно цих доказів ми повинні вважати його керованим об'єктом.
Малік Халіл

12

Некеровані ресурси - це ті, які виконуються за межами виконання .NET (CLR) (він же - код, який не є .NET). Наприклад, дзвінок до DLL в API Win32 або виклик до.


6

"Некерований ресурс" - це не річ, а відповідальність. Якщо об'єкт володіє некерованим ресурсом, це означає, що (1) деяким суб'єктом, що знаходиться поза ним, маніпулювали таким чином, що може викликати проблеми, якщо його не очистити, і (2) об'єкт має інформацію, необхідну для проведення такої очистки, і несе відповідальність. за це.

Хоча багато типів некерованих ресурсів дуже сильно пов'язані з різними типами об'єктів операційної системи (файли, ручки GDI, виділені блоки пам'яті тощо), не існує єдиного типу сутності, який би поділявся всіма ними, крім відповідальності прибирати. Як правило, якщо об'єкт або несе відповідальність за очищення, він матиме метод Dispose, який дає йому змогу виконувати всі очищення, за які він несе відповідальність.

У деяких випадках об’єкти дозволяють допустити можливість того, що вони можуть бути покинуті без того, щоб хтось покликав спочатку розпоряджатися. GC дозволяє об’єктам запитувати сповіщення про те, що вони були залишені (зателефонувавши у програму під назвою Finalize), і об’єкти можуть використовувати це сповіщення для самостійного проведення очищення.

Такі терміни, як "керований ресурс" та "некерований ресурс", на жаль, використовуються різними людьми для позначення різних речей; відверто подумайте, що корисніше думати з точки зору об'єктів як про неприйняття будь-якої відповідальності за прибирання, чи за відповідальність за очищення, за яку слід потурбуватися лише за виклику утилізації, або за відповідальність за очищення, за яку слід піклуватися через Dispose, але яка може також опікується Finalize.


5

Основна відмінність керованого та некерованого ресурсу полягає в тому, що збирач сміття знає про всі керовані ресурси, в певний момент часу GC зійде і очистить усю пам'ять та ресурси, пов'язані з керованим об'єктом. GC не знає про некеровані ресурси, такі як файли, потік та ручки, тому якщо ви не очистите їх явно у своєму коді, то у вас з’явиться витоки пам'яті та заблоковані ресурси.

Вкрадений звідси , сміливо читайте всю публікацію.


2

Будь-який ресурс, для якого виділена пам'ять у керованій купі .NET, є керованим ресурсом. CLR цілком усвідомлює подібну пам’ять і зробить усе, щоб переконатися, що вона не залишиться сиротою. Все інше некероване. Наприклад, взаємодія з COM може створити об'єкти в просторі пам'яті процесора, але CLR не буде дбати про це. У цьому випадку керований об’єкт, який здійснює дзвінки через керовану межу, повинен нести відповідальність за все, що знаходиться поза ним.


0

Давайте спочатку розберемося, як програми VB6 або C ++ (додатки, які не є Dotnet) використовували для виконання. Ми знаємо, що комп'ютери розуміють лише код машинного рівня. Код машинного рівня також називають нативним або двійковим кодом. Отже, коли ми виконуємо програму VB6 або C ++, відповідний компілятор мови компілює відповідний вихідний код мови у нативний код, який потім може бути зрозумілий базовій операційній системі та апаратному забезпеченню.

Рідний код (Unmanaged Code) є специфічним (рідним) для операційної системи, на якій він генерується. Якщо взяти цей скомпільований нативний код і спробувати запустити в іншій операційній системі, він не вдасться. Тому проблема з цим стилем виконання програми полягає в тому, що він не переноситься з однієї платформи на іншу.

Давайте тепер розберемося, як виконується програма .Net. Використовуючи dotnet, ми можемо створювати різні типи додатків. Кілька поширених типів програм .NET включають веб-, Windows, консольні та мобільні додатки. Незалежно від типу програми, під час виконання будь-якої програми .NET відбувається таке

  1. Додаток .NET компілюється на проміжну мову (IL). IL також називають загальною проміжною мовою (CIL) та проміжною мовою Microsoft (MSIL). І .NET, і не .NET програми генерують збірку. Асамблеї мають розширення .DLL або .EXE. Наприклад, якщо ви компілюєте додаток Windows або Console, ви отримуєте .EXE, де, якби під час компіляції веб-проекту чи бібліотечного проекту класу ми отримували .DLL. Різниця між збіркою .NET і NON .NET полягає в тому, що збірка DOTNET знаходиться в проміжному мовному форматі, де як NON DOTNET-збірка знаходиться у форматі коду.

  2. Програми NON DOTNET можуть працювати безпосередньо над операційною системою, де додатки DOTNET запускаються поверх віртуального середовища, що називається загальною мовою виконання (CLR). CLR містить компонент під назвою Just In-Time Compiler (JIT), який перетворить проміжну мову в основний код, який може зрозуміти базова операційна система.

Так, у .NET виконання програми складається з 2 кроків 1. Компілятор мови, компілює вихідний код у проміжний мову (IL) 2. Компілятор JIT в CLR перетворює, IL в нативний код, який потім може бути запущений в базовій операційній системі .

Оскільки збірка .NET виконується у форматі мови Intermedaite, а не є власним кодом, .NET збірки переносяться на будь-яку платформу, якщо цільова платформа має загальну мову виконання (CLR). CLR цільової платформи перетворює мову Intermedaite в нативний код, який може зрозуміти базова операційна система. Проміжну мову називають також керованим кодом. Це тому, що CLR управляє кодом, який працює всередині нього. Наприклад, у програмі VB6 розробник несе відповідальність за розподіл пам'яті, споживаної об'єктом. Якщо програміст забуде виділити пам'ять, ми можемо зіткнутися з труднощами виявити винятки з пам'яті. З іншого боку, .NET-програмісту не потрібно турбуватися про розподіл пам'яті, споживаної об'єктом. CLR забезпечує автоматичне управління пам’яттю, також відоме як збір сміття. Крім того, від вивезення сміття є кілька інших переваг, наданих CLR, про які ми поговоримо на наступній сесії. Оскільки CLR керує та виконує проміжну мову, її (IL) також називають керованим кодом.

.NET підтримує різні мови програмування, такі як C #, VB, J # і C ++. C #, VB і J # можуть генерувати лише керований код (IL), де як C ++ може генерувати як керований код (IL), так і некерований код (Native code).

Народний код не зберігається постійно ніде, після закриття програми нативний код викидається. Коли ми знову виконуємо програму, нативний код знову генерується.

Програма .NET схожа на виконання програми java. У Java у нас є байт-коди та JVM (віртуальна машина Java), де, як у .NET, ми проміжні мови та CLR (загальна мова виконання)

Про це йдеться за цим посиланням - Він чудовий вихователь. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.