MS公开的gc.cs源码

// ==++==
// 
//   
//    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"]/*' />
    public sealed class GC {
    
        
// This class contains only static methods and cannot be instantiated.
        private GC() {
        }

    
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        
private static extern int GetGenerationWR(IntPtr handle);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        
private static extern long nativeGetTotalMemory();

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        
private static extern void nativeCollectGeneration(int generation);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        
private static extern int nativeGetMaxGeneration();
    
        
// Returns the generation that obj is currently in.
        
//
        /// <include file='doc\GC.uex' path='docs/doc[@for="GC.GetGeneration"]/*' />
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        
public static extern int GetGeneration(Object obj);
    
        
// Forces a collection of all generations from 0 through Generation.
        
//
        /// <include file='doc\GC.uex' path='docs/doc[@for="GC.Collect"]/*' />
        public static void Collect(int generation) {
            
if (generation<0{
                
throw new ArgumentOutOfRangeException("generation", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
            }

            nativeCollectGeneration(generation);
        }

    
        
// Garbage Collect all generations.
        
//
        /// <include file='doc\GC.uex' path='docs/doc[@for="GC.Collect1"]/*' />
        public static void 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)]
        
public static extern void KeepAlive(Object obj);

        
// Returns the generation in which wo currently resides.
        
//
        /// <include file='doc\GC.uex' path='docs/doc[@for="GC.GetGeneration1"]/*' />
        public static int 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"]/*' />
        public static int MaxGeneration {
            
get return nativeGetMaxGeneration(); }
        }


        
/// <include file='doc\GC.uex' path='docs/doc[@for="GC.WaitForPendingFinalizers"]/*' />
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        
public static extern void 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)]
        
internal static extern void nativeSuppressFinalize(Object o);

        
/// <include file='doc\GC.uex' path='docs/doc[@for="GC.SuppressFinalize"]/*' />
        public static void SuppressFinalize(Object obj)
        
{
            
if (obj == null)
                
throw new 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)]
        
private static extern void nativeReRegisterForFinalize(Object o);
        
        
/// <include file='doc\GC.uex' path='docs/doc[@for="GC.ReRegisterForFinalize"]/*' />
        public static void ReRegisterForFinalize(Object obj)
        
{
            
if (obj == null)
                
throw new 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"]/*' />
        public static long 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)]
        
private static extern MethodBase nativeGetCurrentMethod(ref StackCrawlMark stackMark);

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        
private static extern void SetCleanupCache();

        
private static ClearCacheHandler m_cacheHandler;

        
internal static event 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
        internal static void FireCacheEvent() {
            BCLDebug.Trace(
"CACHE""Called FileCacheEvent");
            
if (m_cacheHandler!=null{
                m_cacheHandler(
nullnull);
                m_cacheHandler 
= null;
            }

        }

    }
        
    
}

posted on 2005-08-04 00:53  wanna  阅读(596)  评论(0编辑  收藏  举报