Yönetilmeyen kaynaklar tam olarak nedir?


Yanıtlar:


177

Yönetilen kaynaklar temel olarak çöp toplayıcı tarafından yönetilen "yönetilen bellek" anlamına gelir. Yönetilen bir nesneye (yönetilen belleği kullanan) artık başvurunuz yoksa, çöp toplayıcı (sonunda) bu belleği sizin için serbest bırakır.

Yönetilmeyen kaynaklar o zaman çöp toplayıcının bilmediği her şeydir. Örneğin:

  • Dosyaları aç
  • Ağ bağlantılarını aç
  • Yönetilmeyen bellek
  • XNA'da: köşe tamponları, dizin tamponları, dokular vb.

Normalde, yönetilmeyen nesneye ilişkin tüm referansları kaybetmeden önce bu yönetilmeyen kaynakları serbest bırakmak istersiniz . Bunu Dispose, o nesneyi çağırarak veya (C # 'da) sizin için usingçağıracak ifadeyi kullanarak Disposeyaparsınız.

DisposeYönetilmeyen kaynaklarınızı doğru şekilde ihmal ederseniz , bu kaynağı içeren nesne çöp toplandığında (bu "sonlandırma") çöp toplayıcı sonunda sizin için işleyecektir. Ancak çöp toplayıcı, yönetilmeyen kaynakları bilmediği için, bunları serbest bırakmanın ne kadar kötü olduğunu söyleyemez - bu nedenle programınızın kötü performans göstermesi veya kaynakların tamamen tükenmesi mümkündür.

Yönetilmeyen kaynakları işleyen bir sınıfı kendiniz uygularsanız Dispose, Finalizedoğru bir şekilde uygulamak size kalmıştır .


7
Açık Veritabanı bağlantısı hangi kategoriye girer? Yönetilen / Yönetilmeyen?
Deviprasad Das

8
+1 Diğer yanıtlar, aradığınız önemli noktayı kaçırıyor Yönettiği yönetilmeyen kaynağın dahili olarak serbest bırakılmasını yöneten (örneğin dosya tanıtıcısı, GDI + bitmap, ...) ve yönetilmeyen kaynaklara doğrudan erişiyorsanız ( PInvoke vb.) Bunu halletmeniz gerekir.
Ian Mercer

2
@Dev: Yönetilmeyen - GC bu konuda bilmediği için (bazı varsayımsal yönetilen bellek veritabanı kullanmadığınız varsayılarak). Ancak, bağlantı nesnesinin kendisi yönetilmeyen bir kaynağa sahip olmayabilir. Tahminen veritabanı bağlantısı açık bir dosya veya ağ bağlantısı kullanan bir yere - ama öyle mümkün başka bir nesne (bağlantı nesnesi hariç) işlediğini o yönetilmeyen kaynak (belki veritabanı kütüphane önbelleğe bağlantıları). Dokümanları kontrol edin ve nereden aramanızı Disposeveya kullanmanızı istediğini görün using.
Andrew Russell

11
Bu konuda temel bir yorum / soru var, sadece tür tarafından yönetilen / yönetilmeyen gibi bir nesneyi ilişkilendirebilirsiniz, örneğin, dize yönetilir, DataSet yönetilmeyen (bu yüzden bir Dispose () yöntemi vardır) Veritabanı bağlantıları yönetilmez (çünkü bertaraf ettikleri için), vb. Öyleyse, "Dispose ()" yöntemi varsa, o zaman yönetilmez mi? Buna ek olarak, bir XmlDocument nesnesi ne olurdu? Teşekkürler
Nisan'da

15
@ganders Bu iyi bir kural. Her ne kadar tüm C # sınıfı örneklerinin yönetilen nesneler olduğuna dikkat edin. Bir sınıfın bir örneği ise olabilir yönetilmeyen kaynakları tutun, o sınıf gerektiğini uygulamak IDisposable. Bir sınıf ise yok uygulamak IDisposable, o zaman gerektiğini ile o sınıfın örnekleri elden usingveya Dispose()onlarla bittiğinde. Buna dayanarak, görüşmeniz şunları tutar: Bir sınıf uygularsa IDisposable, muhtemelen yönetilmeyen kaynakları dahili olarak tutar.
Andrew Russell

56

Bazı kullanıcılar açık dosyaları, db bağlantılarını, ayrılan belleği, bitmap'leri, dosya akışlarını vb. Yönetilen kaynaklar arasında, diğerleri yönetilmeyenler arasında sıralar. Yani yönetiliyorlar mı yoksa yönetiliyorlar mı?

Bence yanıt daha karmaşık: .NET'te dosya açtığınızda, muhtemelen bazı yerleşik .NET sınıfı System.IO.File, FileStream veya başka bir şey kullanırsınız. Normal bir .NET sınıfı olduğundan yönetilir. Ama içinde gerçekten kirli dosyayı açmak "kirli iş" (Win32 dll kullanarak işletim sistemi ile iletişim kurar, düşük seviyeli fonksiyonları hatta montajcı talimatları) yapan bir sarıcı. Ve bu, .NET'in bilmediği, yönetilmeyen şeydir. Ancak, montajcı talimatlarını kullanarak dosyayı kendiniz açıp .NET dosya işlevlerini atlayabilirsiniz. Sonra tanıtıcı ve açık dosya yönetilmeyen kaynaklardır.

DB ile aynı: Bazı DB derleme kullanıyorsanız, DbConnection vb. Gibi sınıflarınız vardır, bunlar .NET tarafından bilinir ve yönetilir. Ama yönetilmeyen "kirli işi" sararlar (sunucuda bellek tahsis ederler, onunla bağlantı kurarlar, ...). Bu sarmalayıcı sınıfını kullanmaz ve bazı ağ soketlerini kendiniz açar ve bazı komutları kullanarak kendi garip veritabanınızla iletişim kurarsanız, yönetilmez.

Bu sarmalayıcı sınıfları (Dosya, DbConnection vb.) Yönetilir, ancak sarmalayıcıları kullanmazsanız ve "kirli işi" kendiniz yaparsanız, bunlar sizin gibi yönetilmeyen kaynakları kullanır. Ve bu nedenle bu ambalajlar Dispose / Finalize (Çürüme / Sonlandırma) desenleri uygular. Paketleyiciye artık gerek duyulmadığında programcının yönetilmeyen kaynakları bırakmasına izin vermek ve ambalajı çöp toplandığında serbest bırakmak onların sorumluluğundadır. Sargı, çöp toplayıcı tarafından doğru şekilde toplanacak, ancak içindeki yönetilmeyen kaynaklar Dispose / Finalize (Kullan / Sonlandır) deseni kullanılarak toplanacaktır.

Sınıfınızda yerleşik .NET veya 3. taraf sarıcı sınıfları ve bazı derleyici yönergeleri vb. Tarafından açık dosyalar kullanmıyorsanız, bu açık dosyalar yönetilmez ve imha / sonlandırma modeli uygulamanız GEREKİR. Bunu yapmazsanız, artık kullanmadığınız (dosya işlemi tamamlandı) veya uygulama sona erdikten sonra bile bellek sızıntısı, sonsuza kadar kilitli kaynak vb. Olacaktır.

Ama sizin sorumluluğunuz da bu ambalajları kullanırken. İmha / sonlandırmayı uygulayanlar (bunları tanıyın, IDisposable'ı uyguladıklarını), aynı zamanda atma / sonlandırma deseninizi de uygulayın ve bu sarmalayıcıları bile atın veya yönetilmeyen kaynaklarını serbest bırakmaları için sinyal verin. Bunu yapmazsanız, kaynaklar belirli bir süre sonra serbest bırakılır, ancak hemen serbest bırakılması temizdir (dosyayı hemen kapatın ve dosyayı açık bırakıp rastgele birkaç dakika / saat boyunca bloke etmeyin). Sınıfınızın Dispose yönteminde, kullanılan tüm sarmalayıcılarınızın Dispose yöntemlerini çağırırsınız.


1
Ek netlikte iyi olanunmanaged vs managed resources
şimdi adlandırılmaması gereken.

Cevabınız için teşekkürler. aslında hangi sınıflara Dispose diyoruz?
BKSpurgeon

2
Bu basit. Kullandığınız her sınıfta, IDisposable arabirimini kullanıp kullanmadığını doğrulamalısınız. Evetse, bu tür bir sınıfı bir yöntemde kullanırsanız (örneğin: dosyayı açma, metin saklama, dosyayı kapatma), otomatik olarak Atma işlevini çağıran () {} desenini kullanarak bunu kullanabilirsiniz. Bu sınıfı daha fazla yöntemde kullanırsanız (örneğin: sınıfınız Dosya içerir, yapıcıda dosyayı açar, ardından birkaç yöntem bazı günlükler ekler ...), sınıfınız tarafından IDisposable arabirimini uygulamalı, Dispose / Finalize desenini uygulamalısınız ve bu sınıfın nesnesini uygun şekilde imha edin.
Martas

1
"... bazı yerleşik .NET sınıfı System.IO.File, FileStream veya başka bir şey. Normal bir .NET sınıfı olduğu için yönetiliyor." Saygılarımızla, bu yanlış ve yanıltıcıdır. Onlar yönetilmez . Eğer yönetilselerdi, o zaman bu sınıfları tahsis edebilir ve çöp toplayıcısının tüm kaynakların tahsis edilmesini belirleyici bir şekilde tamamen ele almasını bekleyebilirsiniz. Bununla birlikte, bu, dosya toplayıcıların ve yönetilmeyen kaynakların gerekenden çok daha uzun süre kilitlenmesine ve tutulmasına yol açacaktır, çünkü çöp toplayıcı sınıfı yeniden dağıtmayacak ve potansiyel olarak çok uzun bir süre sonuçlandırmayacaktır.
AaronLS

1
@AaronLS, yorumunuzda "FileStream" i yönetilmeyen olarak anlatarak konuştunuz, ancak işini yapmak için dahili olarak yönetilmeyen kaynaklar kullanmasına rağmen, yönetilen dünyada Microsoft, desen atın. Yönetilen kod, yönetilmeyen kaynakları kullanmadığı anlamına gelmez. Ancak, Microsoft bu tür nesneler için IDisposable uygulamak iyi bir iş çıkardı. Bu, IDisposable'ı uyguladığı gerçeği ile kanıtlanmıştır. Bu kanıtlarla ilgili olarak, onu yönetilen bir nesne olarak düşünmeliyiz.
Malik Khalil

12

Yönetilmeyen kaynaklar, .NET çalışma zamanı (CLR) (diğer bir deyişle .NET dışı kod.) Dışında çalışan kaynaklardır. Örneğin, Win32 API'sinde bir DLL çağrısı veya C ++ ile yazılmış bir .dll çağrısı.


6

"Yönetilmeyen bir kaynak" bir şey değil, bir sorumluluktur. Bir nesnenin yönetilmeyen bir kaynağı varsa, bu, (1) dışındaki bazı varlıkların temizlenmediği takdirde sorunlara neden olacak şekilde manipüle edildiği ve (2) nesnenin bu tür bir temizleme gerçekleştirmek için gerekli bilgilere sahip olduğu ve sorumlu olduğu anlamına gelir. yapmak için.

Birçok yönetilmeyen kaynak türü, çeşitli işletim sistemi varlıklarıyla (dosyalar, GDI tutamaçları, ayrılmış bellek blokları, vb.) Çok güçlü bir şekilde ilişkili olsa da, bunların sorumluluğu dışında herkes tarafından paylaşılan tek bir varlık türü yoktur. Temizlemek. Genellikle, bir nesnenin temizleme gerçekleştirme sorumluluğu varsa, kendisine sorumlu olduğu tüm temizliği gerçekleştirmesini bildiren bir Dispose yöntemi olacaktır.

Bazı durumlarda, nesneler önce Dispose çağrısı yapılmadan terk edilmeleri olasılığına izin verir. GC, nesnelerin terk edildiğine dair bildirim istemesine izin verir (Sonlandır adı verilen bir yordamı çağırarak) ve nesneler bu bildirimi temizleme işlemi gerçekleştirmek için kullanabilir.

"Yönetilen kaynak" ve "yönetilmeyen kaynak" gibi terimler maalesef farklı insanlar tarafından farklı şeyler ifade etmek için kullanılır; Açıkçası, nesneler açısından, herhangi bir temizlik sorumluluğu olmaması, yalnızca Dispose çağrıldığında halledilecek temizlik sorumluluğuna sahip olmak veya Dispose yoluyla halledilmesi gereken temizlik sorumluluğuna sahip olmak, ancak ayrıca Finalize tarafından da halledilir.


5

Yönetilen ve yönetilmeyen bir kaynak arasındaki temel fark, çöp toplayıcının yönetilen tüm kaynakları bilmesi, bir noktada GC'nin gelip yönetilen bir nesneyle ilişkili tüm belleği ve kaynakları temizlemesidir. GC, dosyalar, akış ve tanıtıcılar gibi yönetilmeyen kaynaklar hakkında bilgi sahibi değildir, bu nedenle bunları kodunuzda açıkça temizlemezseniz, bellek sızıntıları ve kilitli kaynaklar elde edersiniz.

Buradan çalındığında , tüm yazıyı okumaktan çekinmeyin.


2

Belleğin .NET tarafından yönetilen yığınında ayrıldığı tüm kaynaklar Yönetilen bir kaynaktır. CLR bu tür bir belleğin tamamen farkındadır ve yetim kalmadığından emin olmak için her şeyi yapacaktır. Başka hiçbir şey yönetilmez. Örneğin, COM ile birlikte çalışma, işlem bellek alanında nesneler oluşturabilir, ancak CLR bununla ilgilenmez. Bu durumda, yönetilen sınırlar boyunca arama yapan yönetilen nesne, bunun ötesindeki herhangi bir şeyin sorumluluğuna sahip olmalıdır.


0

Önce VB6 veya C ++ programlarının (Dotnet dışı uygulamalar) nasıl yürütüldüğünü anlayalım. Bilgisayarların yalnızca makine seviyesi kodunu anladığını biliyoruz. Makine seviyesi kodu yerel veya ikili kod olarak da adlandırılır. Bu nedenle, bir VB6 veya C ++ programı yürüttüğümüzde, ilgili dil derleyicisi, ilgili dil kaynak kodunu yerel koda derler, bu da temel işletim sistemi ve donanım tarafından anlaşılabilir.

Yerel kod (Yönetilmeyen Kod), oluşturulduğu işletim sistemine özgüdür (yerel). Bu derlenmiş yerel kodu alıp başka bir işletim sisteminde çalıştırmayı denerseniz başarısız olur. Dolayısıyla, bu program yürütme stilindeki sorun, bir platformdan başka bir platforma taşınabilir olmamasıdır.

Şimdi bir .Net programının nasıl çalıştığını anlayalım. Dotnet kullanarak farklı türlerde uygulamalar oluşturabiliriz. Sık kullanılan .NET uygulama türlerinden bazıları Web, Windows, Konsol ve Mobil Uygulamalar'dır. Uygulama türünden bağımsız olarak, herhangi bir .NET uygulamasını çalıştırdığınızda aşağıdakiler gerçekleşir

  1. .NET uygulaması Orta dil (IL) olarak derlenir. IL, Ortak Ara dil (CIL) ve Microsoft Ara dil (MSIL) olarak da adlandırılır. Hem .NET hem de .NET dışı uygulamalar bir montaj oluşturur. Montajların uzantısı .DLL veya .EXE'dir. Örneğin, bir pencere veya Konsol uygulaması derlerseniz, bir web veya Sınıf kütüphanesi projesini derlediğimizde bir .DLL aldığımız gibi bir .EXE alırsınız. .NET ve NON .NET derlemesi arasındaki fark, DOTNET Assembly'nin ara dil biçiminde olması ve NON DOTNET derlemesinin yerel kod biçiminde olmasıdır.

  2. DOTNET OLMAYAN uygulamalar doğrudan işletim sisteminin üstünde çalışabilir; DOTNET uygulamaları Ortak Dil Çalışma Zamanı (CLR) olarak adlandırılan bir sanal ortam üzerinde çalışır. CLR, Ara dili, temel işletim sisteminin anlayabileceği yerel koda dönüştürecek Just In-Time Compiler (JIT) adlı bir bileşen içerir.

Bu nedenle, .NET'te uygulama yürütme 2 adımdan oluşur. Dil derleyici, Kaynak Kodunu Orta Dil (IL) olarak derler 2. CLR'deki JIT derleyicisi, IL'yi daha sonra temel işletim sisteminde çalıştırılabilen yerel koda dönüştürür. .

Bir .NET derlemesi yerel kod değil Intermedaite Dil biçiminde olduğundan, hedef derleme Ortak Dil Çalışma Zamanı'na (CLR) sahip olduğu sürece .NET derlemeleri herhangi bir platforma taşınabilir. Hedef platformun CLR'si Intermedaite Dilini, temel işletim sisteminin anlayabileceği yerel koda dönüştürür. Orta Dile yönetilen kod da denir. Bunun nedeni CLR'nin içinde çalışan kodu yönetmesidir. Örneğin, bir VB6 programında, geliştirici bir nesne tarafından tüketilen belleğin ayrılmasından sorumludur. Bir programcı belleği ayırmayı unutursa, bellek istisnalarını saptamak zor olabilir. Öte yandan, bir .NET programcısının bir nesne tarafından tüketilen belleği ayırma konusunda endişelenmesine gerek yoktur. Çöp toplama olarak da bilinen otomatik bellek yönetimi CLR tarafından sağlanır. Apart, çöp toplamadan, CLR tarafından sağlanan ve daha sonraki bir oturumda tartışacağımız başka faydalar da vardır. CLR, Ara Dili yönettiği ve yürüttüğü için, bu dil (IL) de yönetilen kod olarak adlandırılır.

.NET, C #, VB, J # ve C ++ gibi farklı programlama dillerini destekler. C #, VB ve J # yalnızca yönetilen kod (IL) oluşturabilir, burada C ++ hem yönetilen kodu (IL) hem de yönetilmeyen kodu (Yerel kod) oluşturabilir.

Yerel kod hiçbir yerde kalıcı olarak depolanmaz, programı kapattıktan sonra yerel kod awaya atılır. Programı tekrar yürüttüğümüzde, yerel kod tekrar oluşturulur.

.NET programı, java programının yürütülmesine benzer. Java'da bayt kodlarımız ve JVM (Java Sanal Makinesi) var, burada .NET'te olduğu gibi Ara Dil ve CLR (Ortak Dil Çalışma Zamanı)

Bu, bu bağlantıdan sağlanır - O harika bir öğretmendir. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.