Co należy rozumieć pod pojęciem „zarządzanych” i „niezarządzanych” zasobów w .NET?

Odpowiedzi:

80

Termin „niezarządzany zasób” jest zwykle używany do opisania czegoś, co nie jest bezpośrednio kontrolowane przez moduł odśmiecania pamięci . Na przykład, jeśli otworzysz połączenie z serwerem bazy danych, spowoduje to użycie zasobów na serwerze (do utrzymania połączenia) i prawdopodobnie innych zasobów spoza sieci na komputerze klienckim, jeśli dostawca nie jest napisany w całości w kodzie zarządzanym.

Dlatego dla czegoś takiego jak połączenie z bazą danych, zaleca się napisanie kodu w ten sposób:

using (var connection = new SqlConnection("connection_string_here"))
{
    // Code to use connection here
}

Ponieważ zapewnia to, że .Dispose()jest on wywoływany w obiekcie połączenia, upewniając się, że wszystkie niezarządzane zasoby są czyszczone.

Obrabować
źródło
20
Wyjaśnię to nieco: „niezarządzany zasób” to coś, czego śmieciarz nie będzie wiedział, jak wyczyścić, jeśli zostanie porzucony. Na przykład subskrypcja obiektu krótkotrwałego na zdarzenie z obiektu o długiej żywotności byłaby zasobem niezarządzanym, mimo że oba obiekty są pod kontrolą modułu wyrzucania elementów bezużytecznych, ponieważ GC nie będzie miał możliwości dowiedzenia się, że subskrypcja powinien zostać usunięty, jeśli subskrybent zostanie porzucony, a wydawca nie. Jeśli w trakcie życia wydawcy można by utworzyć i porzucić nieograniczoną liczbę subskrybentów, spowodowałoby to wyciek pamięci.
supercat
12
Dodatkowe wyjaśnienie: SqlConnection (lub FileStream itp.) To zarządzane zasoby, które wewnętrznie używają niezarządzanych zasobów, o których GC nie wie.
jimvfr
2
jimvfr ma rację, SqlConnection to przykład zarządzanych zasobów. Przykładem niezarządzanych zasobów jest sytuacja, gdy musimy przydzielić pamięć z pamięci niezarządzanej za pomocą metody Marshal.AllocHGlobal () jest to zasób niezarządzany, w tym przypadku najlepszą praktyką jest użycie destruktora (~ ctor) i wywołanie metody Marshal.FreeHGlobal () uwolnić tę pamięć.
Ygor Thomaz
czy możesz podać przykład dla zasobów zarządzanych i niezarządzanych.
Radha Manohar
32

Zasoby zarządzane to takie, które są czystym kodem .NET, zarządzane przez środowisko wykonawcze i znajdują się pod jego bezpośrednią kontrolą.

Zasoby niezarządzane to takie, które nie są. Uchwyty plików, przypięta pamięć, obiekty COM, połączenia z bazą danych itp.

Oded
źródło
13

W pytaniach i odpowiedziach Czym są niezarządzane zasoby? 1 , Bruce Wood napisał co następuje:

Myślę o terminach „zarządzany” i „niezarządzany” w ten sposób:

„Zarządzane” oznacza wszystko w piaskownicy .NET. Dotyczy to wszystkich klas .NET Framework.

„Niezarządzany” odnosi się do obszarów dzikich poza piaskownicą .NET. Obejmuje to wszystko, co jest zwracane przez wywołania funkcji Win32 API.

Jeśli nigdy nie wywołasz funkcji API Win32 i nie odzyskasz żadnych obiektów „obsługi” Win32, oznacza to, że nie masz żadnych niezarządzanych zasobów. Pliki i strumienie otwierane za pomocą metod klasy .NET Framework są zarządzanymi opakowaniami.

Komentarz: Być może nie posiadających zasób niezarządzanej bezpośrednio . Jednak możesz pośrednio przechowywać niezarządzany zasób za pośrednictwem zarządzanej „klasy opakowania”, takiej jak System.IO.FileStream . Taka klasa opakowania zwykle implementuje IDisposable (bezpośrednio lub przez dziedziczenie).

... wiele zarządzanych obiektów (.NET Framework) zawiera w sobie niezarządzane zasoby i prawdopodobnie zechcesz je jak najszybciej pozbyć się () lub przynajmniej zaoferować dzwoniącym możliwość zrobienia tego. W tym miejscu pojawia się napisanie własnej metody Dispose (). Zasadniczo implementacja IDisposable () robi za Ciebie dwie rzeczy:

  1. Pozwala pozbyć się wszelkich zasobów, które zostały pobrane bezpośrednio z systemu operacyjnego za plecami platformy .NET (zasoby niezarządzane).

  2. Pozwala tobie i twoim dzwoniącym uwolnić potężne obiekty .NET / obiekty .NET, które trzymają cenne zasoby w swoich brudnych małych rączkach, które ty / twoi dzwoniący chcecie teraz uwolnić .

Komentarz: Implementując, IDisposablea tym samym udostępniając Dispose()metodę, umożliwiasz użytkownikowi Twojej klasy zwalnianie w sposób deterministyczny wszelkich niezarządzanych zasobów, które są przechowywane przez instancję Twojej klasy.


1 Link pierwotnie udostępniony w odpowiedzi Sachin Shanbhag . Cytowany materiał z dnia 2005-11-17. Zwróć uwagę, że przytoczoną przeze mnie treść lekko skopiowałem.

DavidRR
źródło
5

Podstawowa różnica między zasobem zarządzanym i niezarządzanym polega na tym, że moduł wyrzucania elementów bezużytecznych wie o wszystkich zarządzanych zasobach, w pewnym momencie pojawi się GC i wyczyści całą pamięć i zasoby skojarzone z zarządzanym obiektem. GC nie wie o niezarządzanych zasobach, takich jak pliki, strumienie i uchwyty, więc jeśli nie wyczyścisz ich jawnie w swoim kodzie, skończy się to na wyciekach pamięci i zablokowanych zasobach.

Aby uzyskać więcej informacji - http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources

Sachin Shanbhag
źródło
1
„Ideą interfejsu IDisposable jest umożliwienie czyszczenia zasobów w sposób deterministyczny i czyszczenia zasobów niezarządzanych.” Super!
zionpi
0

Zarządzane zasoby to zasoby, które mogą zostać zwolnione przez moduł odśmiecania pamięci, a niezarządzane zasoby nie mogą zostać zwolnione przez moduł odśmiecania pamięci.

indygowiec
źródło