Why can .NET not have memory leaks?

前端 未结 16 1380
春和景丽
春和景丽 2020-12-07 16:17

Ignoring unsafe code, .NET cannot have memory leaks. I\'ve read this endlessly from many experts and I believe it. However, I do not understand why this is so.

It is

16条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-07 17:11

    You can absolutely have memory leaks in .NET code. Some objects will, in some cases, root themselves (though these are typically IDisposable). Failing to call Dispose() on an object in this case will absolutely cause a real, C/C++ style memory leak with an allocated object that you have no way to reference.

    In some cases, certain timer classes can have this behavior, as one example.

    Any case where you have an asynchronous operation that may reschedule itself, you have a potential leak. The async op will typically root the callback object, preventing a collection. During execution, the object is rooted by the executing thread, and then the newly-scheduled operation re-roots the object.

    Here's some sample code using System.Threading.Timer.

    public class Test
    {
        static public int Main(string[] args)
        {
            MakeFoo();
            GC.Collect();
            GC.Collect();
            GC.Collect();
            System.Console.ReadKey();
            return 0;
        }
    
        private static void MakeFoo()
        {
            Leaker l = new Leaker();
        }
    }
    
    internal class Leaker
    {
        private Timer t;
        public Leaker()
        {
            t = new Timer(callback);
            t.Change(1000, 0);
        }
    
        private void callback(object state)
        {
            System.Console.WriteLine("Still alive!");
            t.Change(1000, 0);
        }
    }
    

    Much like GlaDOS, the Leaker object will be indefinitely "still alive" - yet, there is no way to access the object (except internally, and how can the object know when it's not referenced anymore?)

提交回复
热议问题