Güncelleme (1 Aralık 2009):
Bu cevabı değiştirmek ve orijinal cevabın kusurlu olduğunu kabul etmek istiyorum.
Orijinal analiz , kesinleştirme gerektiren nesneler için geçerlidir ve doğru, derinlemesine bir anlayış olmadan uygulamaların yüzeyde kabul edilmemesi gerektiği nokta hala geçerlidir.
Ancak, DataSets, DataViews, DataTables'ın yapıcılarındaki sonlandırmayı bastırdığı ortaya çıkıyor - bu yüzden onlara Dispose () çağrılması açıkça hiçbir şey yapmıyor.
Muhtemelen bu, yönetilmeyen kaynaklara sahip olmadıkları için olur; bu nedenle MarshalByValueComponent'in yönetilmeyen kaynaklara izin vermesine rağmen , bu özel uygulamalara ihtiyaç yoktur ve bu nedenle sonlandırmayı bırakabilir.
(.NET yazarlarının normalde en fazla belleği işgal eden türlerde sonlandırmayı bastırmaya özen göstermeleri, bu uygulamanın genel olarak sonlandırılabilir türler için önemini ifade eder.)
Buna rağmen, .NET Framework'ün (neredeyse 8 yıl önce) başlaması oldukça şaşırtıcı olduğundan (parçaları birleştirmek için çelişkili, belirsiz bir malzemeyi elemek için esas olarak kendi cihazlarınıza bırakıldığınız için) bu ayrıntıların hala belgelenmediği zaman zaman sinir bozucu olmakla birlikte, her gün güvendiğimiz çerçevenin daha kapsamlı bir şekilde anlaşılmasını sağlar).
Çok fazla okumadan sonra, benim anlayışım:
Bir nesne tamamlanmasına gerektiriyorsa, o olabilir o ihtiyacı daha uzun bellek işgal - İşte sebebi: tanımlar bir yoketme) finalizable kabul edilir bir türünden bir yıkıcı tanımlar (veya devralır a) Her tür; b) Tahsis edildiğinde (kurucu çalışmadan önce), Sonlandırma kuyruğuna bir işaretçi yerleştirilir; c) Sonlandırılabilir bir nesne normalde 2 koleksiyonun geri kazanılmasını gerektirir (standart 1 yerine); d) Sonlandırmanın bastırılması, sonlandırma kuyruğundan bir nesneyi kaldırmaz (SOS'ta! FinalizeQueue tarafından bildirildiği gibi) Bu komut yanıltıcıdır; Sonlandırma kuyruğunda (kendi içinde) hangi nesnelerin olduğunu bilmek yardımcı olmaz; Sonlandırma kuyruğunda hangi nesnelerin bulunduğunu ve hala sonlandırma gerektirdiğini bilmek yardımcı olacaktır (bunun için bir komut var mı?)
Sonlandırmanın bastırılması, nesnenin başlığında, çalışma zamanına, Sonlandırıcının çağrılması gerekmediğini (Kırılabilir kuyruğu taşımasına gerek olmadığını) gösteren biraz kapanır; Sonuçlandırma kuyruğunda kalır (ve SOS'taki FinalizeQueue tarafından rapor edilmeye devam eder)
DataTable, DataSet, DataView sınıflarının tümü, yönetilemeyen kaynakları (potansiyel olarak) işleyebilen sonlandırılabilir bir nesne olan MarshalByValueComponent'e dayanır.
- DataTable, DataSet, DataView yönetilmeyen kaynaklar sunmadığından, kurucularında sonlandırmayı bastırırlar
- Bu alışılmadık bir desen olsa da, arayanı kullanımdan sonra imha etme konusunda endişelenmek zorunda kalmaz
- Bu ve DataTable'ların potansiyel olarak farklı DataSets arasında paylaşılabilmesi gerçeği, DataSets'in alt DataTable'ları atmayı umursamamasıdır.
- Bu aynı zamanda bu nesnelerin SOS'taki! FinalizeQueue altında görüneceği anlamına gelir
- Bununla birlikte, bu nesneler, tamamlanamayan benzerleri gibi, tek bir koleksiyondan sonra yine de geri kazanılabilir olmalıdır
4 (yeni referanslar):
Orijinal Yanıt:
Bu konuda birçok yanıltıcı ve genellikle çok kötü cevaplar var - buraya inen herkes gürültüyü görmezden gelmeli ve aşağıdaki referansları dikkatlice okumalıdır.
Hiç şüphesiz, imha edilmelidir herhangi finalizable nesneler çağırdı.
DataTable vardır finalizable.
Dispose çağrılması belleğin geri kazanımını önemli ölçüde hızlandırır.
MarshalByValueComponent , Dispose ( ) içinde GC.SuppressFinalize (this) öğesini çağırır - bu atlama, bellek geri kazanılmadan önce yüzlerce Gen0 koleksiyonu değilse düzinelerce beklemek zorunda kalır:
Bu temel sonuçlandırma anlayışıyla, çok önemli bazı şeyleri zaten çıkarabiliriz:
İlk olarak, sonlandırılması gereken nesneler yapmayan nesnelerden daha uzun yaşar. Aslında, çok daha uzun yaşayabilirler. Örneğin, gen2'deki bir nesnenin sonlandırılması gerektiğini varsayalım. Sonlandırma zamanlanacaktır ancak nesne hala gen2'de olduğundan, bir sonraki gen2 toplama gerçekleşinceye kadar yeniden toplanmayacaktır. Bu gerçekten çok uzun bir zaman olabilir ve aslında işler yolunda giderse uzun zaman alacaktır, çünkü gen2 koleksiyonları maliyetlidir ve bu nedenle bunların çok seyrek olmasını istiyoruz. Sonlandırılması gereken daha eski nesneler, alanları geri kazanılmadan önce yüzlerce gen0 koleksiyonu olmasa bile düzinelerce beklemek zorunda kalabilir.
İkincisi, sonlandırılması gereken nesneler teminat hasarına neden olur. Dahili nesne işaretçileri geçerli kalması gerektiğinden, yalnızca doğrudan sonlandırma gerektiren nesneler bellekte kalmayacak, aynı zamanda doğrudan ve dolaylı olarak nesnenin referans verdiği her şey de bellekte kalacaktır. Eğer sonlandırma gerektiren tek bir nesne tarafından devasa bir nesne ağacı tutturulmuş olsaydı, o zaman tartıştığımız gibi potansiyel olarak uzun süre tüm ağaç oyalanacaktı. Bu nedenle sonlandırıcıları az miktarda kullanmak ve mümkün olduğunca az dahili nesne işaretçisi olan nesnelere yerleştirmek önemlidir. Az önce verdiğim ağaç örneğinde, sonlandırma ihtiyacı olan kaynakları ayrı bir nesneye taşıyarak ve ağacın kökündeki o nesneye referans tutarak sorunu kolayca önleyebilirsiniz.
Son olarak, sonlandırma gerektiren nesneler sonlandırıcı iş parçacığı için iş oluşturur. Sonlandırma işleminiz karmaşık bir işlemse, tek ve sonlandırıcı iş parçacığı bu adımları gerçekleştirmek için çok zaman harcayacaktır, bu da bir iş birikmesine neden olabilir ve bu nedenle daha fazla nesnenin sonlandırmayı beklemeye devam etmesine neden olur. Bu nedenle, sonuçlandırıcıların mümkün olduğunca az iş yapması hayati önem taşımaktadır. Ayrıca, tüm nesne işaretçileri sonlandırma sırasında geçerli kalmasına rağmen, bu işaretçilerin zaten sonlandırılmış olan nesnelere yol açmış olabileceğini ve bu nedenle yararlı olmadıklarını unutmayın. İşaretçiler geçerli olsa bile, sonlandırma kodunda nesne işaretçileri izlemekten kaçınmak genellikle en güvenlidir. Güvenli, kısa bir sonlandırma kodu yolu en iyisidir.
Gen2'de 100'lerce MB referans edilmemiş DataTables gören birinden alın: Bu çok önemlidir ve bu konudaki cevaplar tarafından tamamen kaçırılmıştır.
Referanslar:
1 -
http://msdn.microsoft.com/tr-tr/library/ms973837.aspx
2 -
http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry
http://www.dotnetfunda.com/articles/article524-net-best-practice-no-2-improve-garbage -collector performanslı-finalizedispose-pattern.aspx kullanılarak
3 -
http://codeidol.com/csharp/net-framework/Inside-the-CLR/Automatic-Memory-Management/