जीसी एक अनुमानित और आरक्षित संसाधन से संबंधित है। वीएम का इस पर कुल नियंत्रण है और किस पर और किस समय सृजन होता है, इस पर कुल नियंत्रण है। यहां कीवर्ड "आरक्षित" और "कुल नियंत्रण" हैं। हैंडल ओएस द्वारा आवंटित किए गए हैं, और संकेत हैं ... प्रबंधित स्थान के बाहर आवंटित संसाधनों के लिए अच्छी तरह से संकेत। इस वजह से, हैंडल और पॉइंटर्स प्रबंधित कोड के अंदर उपयोग करने के लिए प्रतिबंधित नहीं हैं। उनका उपयोग किया जा सकता है - और अक्सर - प्रबंधित और अप्रबंधित कोड द्वारा एक ही प्रक्रिया पर चल रहे हैं।
एक "रिसोर्स कलेक्टर" यह सत्यापित करने में सक्षम होगा कि हैंडल / पॉइंटर का उपयोग किसी प्रबंधित स्थान के भीतर किया जा रहा है या नहीं, लेकिन यह परिभाषा से अनभिज्ञ है कि यह मेमोरी स्पेस के बाहर क्या हो रहा है (और, चीजों को खराब करने के लिए कुछ हैंडल का उपयोग किया जा सकता है) प्रक्रिया सीमाओं के पार)।
एक व्यावहारिक उदाहरण .NET CLR है। कोई कोड लिखने के लिए फ्लेवर्ड C ++ का उपयोग कर सकता है जो प्रबंधित और अप्रबंधित मेमोरी स्पेस दोनों के साथ काम करता है; प्रबंधित और अप्रबंधित कोड के बीच हैंडल, पॉइंटर्स और संदर्भों को पास किया जा सकता है। अनवांटेड कोड को विशेष निर्माणों / प्रकारों का उपयोग करना चाहिए ताकि CLR को प्रबंधित संसाधनों के लिए किए जा रहे संदर्भों पर नज़र रखने की अनुमति मिल सके। लेकिन यह सबसे अच्छा यह कर सकता है। यह हैंडल और पॉइंटर्स के साथ ऐसा नहीं कर सकता है, और कहा कि संसाधन कलेक्टर को नहीं पता होगा कि क्या किसी विशेष हैंडल या पॉइंटर को जारी करना ठीक है।
संपादित करें: .NET CLR के बारे में, मैं .NET प्लेटफॉर्म के साथ C ++ डेवलपमेंट के साथ अनुभवी नहीं हूं। शायद वहाँ विशेष तंत्र हैं जो सीएलआर को प्रबंधित और अप्रबंधित कोड के बीच हैंडल / पॉइंटर्स के संदर्भों पर नज़र रखने की अनुमति देता है। अगर ऐसा है तो सीएलआर उन संसाधनों के जीवनकाल का ध्यान रख सकता है और उन्हें तब जारी कर सकता है जब उनके लिए सभी संदर्भ साफ हो जाएं (ठीक है, कम से कम कुछ परिदृश्यों में यह हो सकता है)। किसी भी तरह से, सर्वोत्तम प्रथाएं तय करती हैं कि हैंडल (विशेष रूप से फाइलों की ओर इशारा करने वाले) और पॉइंटर्स को जल्द से जल्द जारी किया जाए, जिसकी उन्हें जरूरत नहीं है। एक संसाधन कलेक्टर इसका अनुपालन नहीं करेगा, यह एक और कारण नहीं है।
संपादित 2: यह CLR / JVM / VMs-in-in पर अपेक्षाकृत तुच्छ है, किसी विशेष हैंडल को मुक्त करने के लिए कुछ कोड लिखने के लिए यदि यह केवल प्रबंधित स्थान के अंदर उपयोग किया जाता है। .NET में कुछ इस तरह होगा:
// This class offends many best practices, but it would do the job.
public class AutoReleaseFileHandle {
// keeps track of how many instances of this class is in memory
private static int _toBeReleased = 0;
// the threshold when a garbage collection should be forced
private const int MAX_FILES = 100;
public AutoReleaseFileHandle(FileStream fileStream) {
// Force garbage collection if max files are reached.
if (_toBeReleased >= MAX_FILES) {
GC.Collect();
}
// increment counter
Interlocked.Increment(ref _toBeReleased);
FileStream = fileStream;
}
public FileStream { get; private set; }
private void ReleaseFileStream(FileStream fs) {
// decrement counter
Interlocked.Decrement(ref _toBeReleased);
FileStream.Close();
FileStream.Dispose();
FileStream = null;
}
// Close and Dispose the Stream when this class is collected by the GC.
~AutoReleaseFileHandle() {
ReleaseFileStream(FileStream);
}
// because it's .NET this class should also implement IDisposable
// to allow the user to dispose the resources imperatively if s/he wants
// to.
private bool _disposed = false;
public void Dispose() {
if (_disposed) {
return;
}
_disposed = true;
// tells GC to not call the finalizer for this instance.
GC.SupressFinalizer(this);
ReleaseFileStream(FileStream);
}
}
// use it
// for it to work, fs.Dispose() should not be called directly,
var fs = File.Open("path/to/file");
var autoRelease = new AutoReleaseFileHandle(fs);