Why .Net not use smart pointers instead of GC? RRS feed

  • Question

  • Hi, my question is why didn't .Net use smart pointers instead of Garbage Collector to do memory management?

    In that way, the memory will reclaimed automatically when there is no variable reference the object, and memory usage will be always compact, and there is no need for a garbage collector program running.



    Monday, August 6, 2018 6:23 PM

All replies

  • Maybe because smart pointers (based on reference counters, for example) do not prevent memory leaks caused by “circular references”.

    Tuesday, August 7, 2018 4:51 AM
  • Mostly because if you free multiple in-memory objects together, there would be less chance if memory fragmentation.

    In C++ you have pointer so you can have finer control on memory management yourself. In C# unless you enabled "unsafe" feature, you only have "reference" so that kind on control is impossible. Using GC way of memory management enables user to write long running applications without spending too much effort in learning / planning memory usage.

    Btw, I remember at some time point, the .NET design philosophy did encourage "object reuse" (i.e.: if possible don't keep dispose and recreate object, clean and reuse it instead) but seems not the case now (even BCL class like StringBuilder can have significantly poorer performance to clear and reuse it than to just renew it)

    Tuesday, August 7, 2018 6:38 AM
  • .NET was developed before C++ had smart pointers. At the time it was developed, as an answer to Java, GC was the way to go with memory management. STL has introduced much more robust management of memory but care still needs to be taken and large and complex software systems still suffer from memory issues caused by memory allocation in both approaches. The problems are just different.
    Tuesday, August 7, 2018 6:44 AM
  • ".NET was developed before C++ had smart pointers:"

    This is incorrect. Smart pointers have been around since the early days of pointer-like objects (the unofficial Wikipedia source indicates 1965). Official language support for smart pointers came into C++ later but smart pointers have been around a very long time. Back in the heyday of COM and ATL we used smart pointers around COM objects. I believe Boost had smart pointers early in its life as well.

    There are pluses and minuses to smart pointers. On the plus side is deterministic cleanup. At the point the object goes out of scope the memory can be cleaned up. With a GC this isn't true. However at the same time that also means that any code that is time dependent could take longer to run since memory deletion has to occur.

    On the negative side it is possible that a pointer will never get cleaned up with smart pointers. It is the responsibility of the programmer to tell the system when the pointer is no longer needed (either by letting it go out of scope or reassignment). This can get very complex if you start talking about owned/shared pointers. With GC the responsibility is no longer on the programmer so they don't have to be (theoretically) as careful about cleanup. Assuming the GC doesn't have a bug all memory will eventually be cleaned up.

    As mentioned earlier, yet another advantage of a GC is memory clean up. With separate deletes the runtime is responsible for allocating and deallocating memory. The runtime has to handle memory fragmentation issues and it is possible to run out of memory because of fragmentation. With the GC it has a whole view of memory so it can clean up memory and defrag as needed. One of the big differences between a pointer and a .NET object is that a .NET object is a reference to an object, not a pointer. As such an object can move around in memory (during a GC) and the reference is still valid. You cannot really do that with smart pointers. This helps with the fragmentation issues.

    And another advantage is overall performance. As mentioned earlier smart pointers are cleaned up when the stack is popped (generally). This check has to happen every time. If you're passing smart pointers around a lot then you are taking a hit for this. Imagine a recursive call that has a smart pointer (irrelevant whether it is used or not). Each pop requires the pointer to be evaluated. If you make a lot of calls this can be slow. Contrast that with the GC that runs periodically. It make take longer to run but it runs less frequently so (theoretically) it won't slow the system down as much. And with newer versions of the framework it is even async so it won't slow down the main thread anyway.

    Overall I think GC is a better solution than smart pointers. But I wouldn't say that smart pointers are bad. They are solving problems in different ways. In one case the programmer is taking an active role in lifetime while in the other the system is completely responsible. There are benefits to both approaches.

    Michael Taylor

    Wednesday, August 8, 2018 2:34 PM