// ==++== // // // Copyright (c) 2002 Microsoft Corporation. All rights reserved. // // The use and distribution terms for this software are contained in the file // named license.txt, which can be found in the root of this distribution. // By using this software in any fashion, you are agreeing to be bound by the // terms of this license. // // You must not remove this notice, or any other, from this software. // // // ==--== /**//*============================================================ ** ** Class: GC ** ** ** ** Purpose: Exposes features of the Garbage Collector through ** the class libraries. This is a class which cannot be ** instantiated. ** ** Date: November 9, 1998 ** ===========================================================*/ namespace System { //This class only static members and doesn't require the serializable keyword. using System; using System.Security.Permissions; using System.Reflection; using System.Security; using System.Threading; using System.Runtime.CompilerServices; using System.Reflection.Cache; /**////<include file='doc\GC.uex' path='docs/doc[@for="GC"]/*' /> publicsealedclass GC { // This class contains only static methods and cannot be instantiated. private GC() { } [MethodImplAttribute(MethodImplOptions.InternalCall)] privatestaticexternint GetGenerationWR(IntPtr handle); [MethodImplAttribute(MethodImplOptions.InternalCall)] privatestaticexternlong nativeGetTotalMemory(); [MethodImplAttribute(MethodImplOptions.InternalCall)] privatestaticexternvoid nativeCollectGeneration(int generation); [MethodImplAttribute(MethodImplOptions.InternalCall)] privatestaticexternint nativeGetMaxGeneration(); // Returns the generation that obj is currently in. // /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.GetGeneration"]/*' /> [MethodImplAttribute(MethodImplOptions.InternalCall)] publicstaticexternint GetGeneration(Object obj); // Forces a collection of all generations from 0 through Generation. // /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.Collect"]/*' /> publicstaticvoid Collect(int generation) { if (generation<0) { thrownew ArgumentOutOfRangeException("generation", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive")); } nativeCollectGeneration(generation); } // Garbage Collect all generations. // /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.Collect1"]/*' /> publicstaticvoid Collect() { //-1 says to GC all generations. nativeCollectGeneration(-1); } // This method DOES NOT DO ANYTHING in and of itself. It's used to // prevent an object from losing any outstanding references a touch too // early. Users should insert a call to this method near the end of a // method where they must keep an object alive for the duration of that // method, up until this method is called. Here is an example: // // "all you really need is one object with a Finalize method, and a // second object with a Close/Dispose/Done method. Such as the following // contrived example: // // class Foo { // Stream stream = ; // protected void Finalize() { stream.Close(); } // void Problem() { stream.MethodThatSpansGCs(); } // static void Main() { new Foo().Problem(); } // } // // // In this code, Foo will be finalized in the middle of // stream.MethodThatSpansGCs, thus closing a stream still in use." // // If we insert a call to GC.KeepAlive(this) at the end of Problem(), then // Foo doesn't get finalized and the stream says open. /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.KeepAlive"]/*' /> [MethodImplAttribute(MethodImplOptions.InternalCall)] publicstaticexternvoid KeepAlive(Object obj); // Returns the generation in which wo currently resides. // /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.GetGeneration1"]/*' /> publicstaticint GetGeneration(WeakReference wo) { return GetGenerationWR(wo.m_handle); } // Returns the maximum GC generation. Currently assumes only 1 heap. // /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.MaxGeneration"]/*' /> publicstaticint MaxGeneration { get{ return nativeGetMaxGeneration(); } } /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.WaitForPendingFinalizers"]/*' /> [MethodImplAttribute(MethodImplOptions.InternalCall)] publicstaticexternvoid WaitForPendingFinalizers(); // Indicates that the system should not call the Finalize() method on // an object that would normally require this call. // Has the DynamicSecurityMethodAttribute custom attribute to prevent // inlining of the caller. [MethodImplAttribute(MethodImplOptions.InternalCall)] internalstaticexternvoid nativeSuppressFinalize(Object o); /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.SuppressFinalize"]/*' /> publicstaticvoid SuppressFinalize(Object obj) { if (obj ==null) thrownew ArgumentNullException("obj"); nativeSuppressFinalize(obj); } // Indicates that the system should call the Finalize() method on an object // for which SuppressFinalize has already been called. The other situation // where calling ReRegisterForFinalize is useful is inside a finalizer that // needs to resurrect itself or an object that it references. // Has the DynamicSecurityMethodAttribute custom attribute to prevent // inlining of the caller. [MethodImplAttribute(MethodImplOptions.InternalCall)] privatestaticexternvoid nativeReRegisterForFinalize(Object o); /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.ReRegisterForFinalize"]/*' /> publicstaticvoid ReRegisterForFinalize(Object obj) { if (obj ==null) thrownew ArgumentNullException("obj"); nativeReRegisterForFinalize(obj); } // Returns the total number of bytes currently in use by live objects in // the GC heap. This does not return the total size of the GC heap, but // only the live objects in the GC heap. // /**////<include file='doc\GC.uex' path='docs/doc[@for="GC.GetTotalMemory"]/*' /> publicstaticlong GetTotalMemory(bool forceFullCollection) { long size = nativeGetTotalMemory(); if (!forceFullCollection) return size; // If we force a full collection, we will run the finalizers on all // existing objects and do a collection until the value stabilizes. // The value is "stable" when either the value is within 5% of the // previous call to nativeGetTotalMemory, or if we have been sitting // here for more than x times (we don't want to loop forever here). int reps =20; // Number of iterations long newSize = size; float diff; do{ GC.WaitForPendingFinalizers(); GC.Collect(); size = newSize; newSize = nativeGetTotalMemory(); diff = ((float)(newSize - size)) / size; }while (reps-->0&&!(-.05< diff && diff < .05)); return newSize; } [MethodImplAttribute(MethodImplOptions.InternalCall)] privatestaticextern MethodBase nativeGetCurrentMethod(ref StackCrawlMark stackMark); [MethodImplAttribute(MethodImplOptions.InternalCall)] privatestaticexternvoid SetCleanupCache(); privatestatic ClearCacheHandler m_cacheHandler; internalstaticevent ClearCacheHandler ClearCache { add { m_cacheHandler+=value; SetCleanupCache(); } remove { m_cacheHandler-=value; } } //This method is called from native code. If you update the signature, please also update //mscorlib.h and COMUtilNative.cpp internalstaticvoid FireCacheEvent() { BCLDebug.Trace("CACHE", "Called FileCacheEvent"); if (m_cacheHandler!=null) { m_cacheHandler(null, null); m_cacheHandler =null; } } } }
posted on
2005-08-04 00:53wanna
阅读(596)
评论(0)
编辑收藏举报