none
Are my understandings of "Twice actions" for Garbage Collection Right? RRS feed

  • Question

  • Hey everyone here——

    Tell me whether my understanding of the three statements are right or not——XD

    1)When a class without Finalize function, it will be marked as "useless" and garbaged directly.

    2)When a class with Finalize function, it will be first marked, but to unmanaged things, it will be pushed into a "Garbage Queue" and waiting for its being garbaged.——So first Finalize will be called to dispose all the managed and unmanaged things, And second time it will be TOTALLY disposed by GC.

    3)GC.SuppressFinalize(this):means when Finalize is called, no need to do that twice but at the first time when it's marked, it should be directly disposed insteading waiting for the 2nd time to dispose when managed and unmanaged things are both disposed by "Dispose" method.

    Plz quote each of my understanding and tell me RIGHT OR NOT, and give your suggestions if wrong. Don't be sticky or Ambiguous……

    Thx anyway!

    • Edited by TimoYang Tuesday, July 17, 2012 5:35 AM
    Tuesday, July 17, 2012 5:31 AM

Answers

  • Hi Ignoredrei,

    Nice to see you.

    >>1)When a class without Finalize function, it will be marked as "useless" and garbaged directly.

    No, it will be marked as "useless" just when the application code cannot reach it. It doesn't matter with the Finalize method or not.

    >>When a class with Finalize function, it will be first marked, but to unmanaged things, it will be pushed into a "Garbage Queue" and waiting for its being garbaged.

    No,Each time your application creates an object that has a Finalize method, the garbage collector places an entry in the finalization queue that points to that object. The finalization queue contains entries for all the objects in the managed heap that need to have their finalization code called before the garbage collector can reclaim their memory.

    >>So first Finalize will be called to dispose all the managed and unmanaged things,

    No, generally, just Unmanaged things.

    Although the garbage collector is able to track the lifetime of an object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. For these types of objects, the .NET Framework provides the Object.Finalize method, which allows an object to clean up its unmanaged resources properly when the garbage collector reclaims the memory used by the object.

    >>3)GC.SuppressFinalize(this):means when Finalize is called, no need to do that twice

    No, Objects that implement the IDisposable interface can call this method from the IDisposable.Dispose method to prevent the garbage collector from callingObject.Finalize on an object that does not require it.

    I hope this is clear.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by TimoYang Wednesday, July 18, 2012 7:21 AM
    Wednesday, July 18, 2012 6:41 AM
    Moderator

All replies

  • Hi Ignoredrei,

    Nice to see you.

    >>1)When a class without Finalize function, it will be marked as "useless" and garbaged directly.

    No, it will be marked as "useless" just when the application code cannot reach it. It doesn't matter with the Finalize method or not.

    >>When a class with Finalize function, it will be first marked, but to unmanaged things, it will be pushed into a "Garbage Queue" and waiting for its being garbaged.

    No,Each time your application creates an object that has a Finalize method, the garbage collector places an entry in the finalization queue that points to that object. The finalization queue contains entries for all the objects in the managed heap that need to have their finalization code called before the garbage collector can reclaim their memory.

    >>So first Finalize will be called to dispose all the managed and unmanaged things,

    No, generally, just Unmanaged things.

    Although the garbage collector is able to track the lifetime of an object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. For these types of objects, the .NET Framework provides the Object.Finalize method, which allows an object to clean up its unmanaged resources properly when the garbage collector reclaims the memory used by the object.

    >>3)GC.SuppressFinalize(this):means when Finalize is called, no need to do that twice

    No, Objects that implement the IDisposable interface can call this method from the IDisposable.Dispose method to prevent the garbage collector from callingObject.Finalize on an object that does not require it.

    I hope this is clear.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by TimoYang Wednesday, July 18, 2012 7:21 AM
    Wednesday, July 18, 2012 6:41 AM
    Moderator
  • Hi again Mike:D

    THANKS FOR UR GREATE ANSWERS, Additional question——

    >>3)GC.SuppressFinalize(this):means when Finalize is called, no need to do that twice

    No, Objects that implement the IDisposableinterface can call this method from the IDisposable.Disposemethod to prevent the garbage collector from callingObject.Finalizeon an object that does not require it.

    I don't understand why a class that implements the interface of IDisposible can prevent Finalize?U should see that IDisposible can only dispose managed things manually exposed directly to the client, and sometimes we can overrload a Disposible(bool flag) and called this directly in Finalize method to release umanaged things. So Finalize will be finally called……

    so I still cannot understand "SuperssFinalize(this)"……:(

    Wednesday, July 18, 2012 7:13 AM
  • Now I offer you a snippet of codes from MSDN to explain in details——

    using System;
    using System.ComponentModel;
    
    public class DisposeExample
    {
        public class MyResource: IDisposable
        {
            private IntPtr handle;
    
            private Component component = new Component();
    
            private bool disposed = false;
    
    
            public MyResource(IntPtr handle)
            {
                this.handle = handle;
            }
    
    
            public void Dispose()
            {
                Dispose(true);
    
                GC.SuppressFinalize(this);
            }
    
            private void Dispose(bool disposing)
            {
    
                if(!this.disposed)
                {
    
                    if(disposing)
                    {
                        component.Dispose();
                    }
    		 
                    CloseHandle(handle);
                    handle = IntPtr.Zero;			
                }
                disposed = true;         
            }
    
            [System.Runtime.InteropServices.DllImport("Kernel32")]
            private extern static Boolean CloseHandle(IntPtr handle);
    
            ~MyResource()      
            {
                Dispose(false);
            }
        }
    
    }
    So I see how it works. But I don't think that's good idea. Why don't we write like this (Attention to the bold ones ……)

    using System;
    using System.ComponentModel;
    
    public class DisposeExample
    {
        public class MyResource: IDisposable
        {
            private IntPtr handle;
    
            private Component component = new Component();
    
            private bool disposed = false;
    
    
            public MyResource(IntPtr handle)
            {
                this.handle = handle;
            }
    
    
            public void Dispose()
            {
                Dispose(false);
            }
    
            private void Dispose(bool disposing)
            {
    
                if(!this.disposed)
                {
    
                    if(disposing)
                    {
                      CloseHandle(handle);
                      handle = IntPtr.Zero;	
                    }
    		
                      //Release managed things here…… 		
                }
                disposed = true;         
            }
    
            [System.Runtime.InteropServices.DllImport("Kernel32")]
            private extern static Boolean CloseHandle(IntPtr handle);
    
            ~MyResource()      
            {
                Dispose(true);
            }
        }
    
    }
    • Edited by TimoYang Wednesday, July 18, 2012 7:21 AM
    Wednesday, July 18, 2012 7:18 AM
  • Hi Ignoredrei,

    >>U should see that IDisposible can only dispose managed things manually

    No, Unmanaged resource: http://msdn.microsoft.com/en-us/library/system.idisposable.dispose(v=vs.100).aspx 

    When you can called Dispose to release the unmanaged resource, there is no necessary to call finalize method to release them again.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, July 18, 2012 7:44 AM
    Moderator