Useless Garbage Collection in C#?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Born

    Useless Garbage Collection in C#?

    Here are my challenges to you:

    1) Suppose object A has to do cleanup before it dies. Also suppose there are
    multiple references to A. How can I determine when and who to call Dispose
    (if you use Dispose for the cleanup).

    2) Suppose there are some other sources who reference A through handles.
    That is, those sources do not reference A directly but through an
    intermediate handle mechanism. The purpose is not to interfere with the
    lifetime management of A, but to use A when it exists and to give it up when
    it's gone.

    Without GC, I can do them pretty easy and good (for example,in C++). But
    now, en... Anybody could give me a solution?





  • =?ISO-8859-1?Q?Arne_Vajh=F8j?=

    #2
    Re: Useless Garbage Collection in C#?

    Born wrote:
    Here are my challenges to you:
    >
    1) Suppose object A has to do cleanup before it dies. Also suppose there are
    multiple references to A. How can I determine when and who to call Dispose
    (if you use Dispose for the cleanup).
    >
    2) Suppose there are some other sources who reference A through handles.
    That is, those sources do not reference A directly but through an
    intermediate handle mechanism. The purpose is not to interfere with the
    lifetime management of A, but to use A when it exists and to give it up when
    it's gone.
    >
    Without GC, I can do them pretty easy and good (for example,in C++). But
    now, en... Anybody could give me a solution?
    If we talk about allocated memory inside .NET, then you don't
    do anything. .NET will handle that for you. You do not do
    any cleanup.

    If you use resources outside of .NET, then you implement
    IDisposable and call Dispose on the object.

    Arne

    Comment

    • Barry Kelly

      #3
      Re: Useless Garbage Collection in C#?

      Born wrote:
      1) Suppose object A has to do cleanup before it dies.
      It is a resource then, and not just memory. GC is for memory, not
      resources.
      Also suppose there are
      multiple references to A. How can I determine when and who to call Dispose
      (if you use Dispose for the cleanup).
      The same way you would in C++.
      2) Suppose there are some other sources who reference A through handles.
      That is, those sources do not reference A directly but through an
      intermediate handle mechanism. The purpose is not to interfere with the
      lifetime management of A, but to use A when it exists and to give it up when
      it's gone.
      You'd usually use WeakReference (if it's only memory you're interested
      in) and possibly subscribe to the death of A (if you're also interested
      in resource usage).
      Without GC, I can do them pretty easy and good (for example,in C++).
      Two things to remember: GC is additive - you can still do manual memory
      management if you must (whether object pooling or other mechanisms), and
      GC is for memory - i.e. collecting the memory used by objects, not
      resources.

      -- Barry

      --

      Comment

      • Born

        #4
        Re: Useless Garbage Collection in C#?


        "Barry Kelly" <barry.j.kelly@ gmail.comwrote in message
        news:5s6rq2dbds o1ctlikhs4kf7lt 9sce9seso@4ax.c om...
        >Also suppose there are
        >multiple references to A. How can I determine when and who to call
        >Dispose
        >(if you use Dispose for the cleanup).
        >
        The same way you would in C++.
        In C++, I use reference counting and smart pointers. Because of the stack
        object capability, the whole process is quite automatic. I don't exactly
        know who triggers the cleanup. But for Dispose in C#, the user must
        explicitly trigger it, which is the problem.


        You'd usually use WeakReference (if it's only memory you're interested
        in) and possibly subscribe to the death of A (if you're also interested
        in resource usage).
        WeakReference seems an alternative for handles. I'm checking it.

        Two things to remember: GC is additive - you can still do manual memory
        management if you must
        I want to develop a reference counting + smart reference mechanism. Although
        it's a waste on GC, it makes the destruction points determined ( good for
        CPU/resource heavy but memory cheap objects ) while alleviates the problem
        of who should trigger the destruction points. However, in order to do that,
        I need stack object capability. I don't know how to do it because my lack of
        experiece about C#.



        Comment

        • Marc Gravell

          #5
          Re: Useless Garbage Collection in C#?

          2: is WeakReference
          1: if the cleanup is unmanaged, then *an* option is a finalizer.
          Personally, I prefer to ascribe lifetime ownership to one (only) of the
          holders, such that it is absolutely responsible for cleaning up after
          itself (via Dispose); I would tend to do this by propegating
          IDisposposable to this holder class, and so-on.

          Marc

          Comment

          • Born

            #6
            Re: Useless Garbage Collection in C#?

            I've checked WeakReference. It seems a good alternative to handles although
            my MSDN 2005 says an exception will be triggered if the referenced object
            has finalized ( I did not experience any exception in my test).


            "Marc Gravell" <marc.gravell@g mail.comwrote in message
            news:1169011158 .809951.127550@ 38g2000cwa.goog legroups.com...
            2: is WeakReference
            1: if the cleanup is unmanaged, then *an* option is a finalizer.
            Personally, I prefer to ascribe lifetime ownership to one (only) of the
            holders, such that it is absolutely responsible for cleaning up after
            itself (via Dispose); I would tend to do this by propegating
            IDisposposable to this holder class, and so-on.
            >
            Marc
            >

            Comment

            • Morten Wennevik [C# MVP]

              #7
              Re: Useless Garbage Collection in C#?

              On Wed, 17 Jan 2007 05:50:01 +0100, Born <wandertop@dlct ek.comwrote:
              >
              "Barry Kelly" <barry.j.kelly@ gmail.comwrote in message
              news:5s6rq2dbds o1ctlikhs4kf7lt 9sce9seso@4ax.c om...
              >
              >>Also suppose there are
              >>multiple references to A. How can I determine when and who to call
              >>Dispose
              >>(if you use Dispose for the cleanup).
              >>
              >The same way you would in C++.
              >
              In C++, I use reference counting and smart pointers. Because of the stack
              object capability, the whole process is quite automatic. I don't exactly
              know who triggers the cleanup. But for Dispose in C#, the user must
              explicitly trigger it, which is the problem.
              >
              >
              The user should not be absolutely required to use it. If the user forgets
              to Dispose, put the cleanup in the Finalizer. To prevent the Finalizer
              from running in case the user do remember to Dispose, use
              GC.SuppressFina lize in the Dispose method.
              >
              >You'd usually use WeakReference (if it's only memory you're interested
              >in) and possibly subscribe to the death of A (if you're also interested
              >in resource usage).
              >
              WeakReference seems an alternative for handles. I'm checking it.
              >
              >
              >Two things to remember: GC is additive - you can still do manual memory
              >management if you must
              >
              I want to develop a reference counting + smart reference mechanism.
              Although
              it's a waste on GC, it makes the destruction points determined ( good for
              CPU/resource heavy but memory cheap objects ) while alleviates the
              problem
              of who should trigger the destruction points. However, in order to do
              that,
              I need stack object capability. I don't know how to do it because my
              lack of
              experiece about C#.
              >
              >
              >


              --
              Happy Coding!
              Morten Wennevik [C# MVP]

              Comment

              • Born

                #8
                Re: Useless Garbage Collection in C#?


                "Born" <wandertop@dlct ek.comwrote in message
                news:eokf0h$8tt $1@news.yaako.c om...
                I've checked WeakReference. It seems a good alternative to handles
                although my MSDN 2005 says an exception will be triggered if the
                referenced object has finalized ( I did not experience any exception in my
                test).
                >
                >
                >

                Sorry it's my misunderstandin g of the MSDN documentation. The exception
                occurs when the WeakReference itself has finalized.



                Comment

                • Barry Kelly

                  #9
                  Re: Useless Garbage Collection in C#?

                  Born wrote:
                  "Barry Kelly" <barry.j.kelly@ gmail.comwrote in message
                  news:5s6rq2dbds o1ctlikhs4kf7lt 9sce9seso@4ax.c om...
                  >
                  Also suppose there are
                  multiple references to A. How can I determine when and who to call
                  Dispose
                  (if you use Dispose for the cleanup).
                  The same way you would in C++.
                  >
                  In C++, I use reference counting and smart pointers.
                  Maybe you're not aware of it, but reference counting is GC too ;)
                  Two things to remember: GC is additive - you can still do manual memory
                  management if you must
                  >
                  I want to develop a reference counting + smart reference mechanism.
                  Why? I suggest you take a careful look at things such as SafeHandle, and
                  read up on the recommendations on how to wrap resources in .NET, and how
                  to properly implement finalizers etc.
                  Although
                  it's a waste on GC, it makes the destruction points determined ( good for
                  CPU/resource heavy but memory cheap objects ) while alleviates the problem
                  of who should trigger the destruction points.
                  Can you describe your CPU/resource heavy types a little more? I think
                  that you may be at risk of trying to apply a C++ solution to a general
                  problem.
                  However, in order to do that,
                  I need stack object capability. I don't know how to do it because my lack of
                  experiece about C#.
                  You could try working with some IDisposable pattern, and ask that users
                  use 'using' statements to protect the resources.

                  -- Barry

                  --

                  Comment

                  • Born

                    #10
                    Re: Useless Garbage Collection in C#?

                    The user should not be absolutely required to use it. If the user forgets
                    to Dispose, put the cleanup in the Finalizer. To prevent the Finalizer
                    from running in case the user do remember to Dispose, use
                    GC.SuppressFina lize in the Dispose method.
                    >
                    If you depend on Finalizer, then there will be a delay between the wanted
                    destroy and the actual destruction. There are two bad effects for it:

                    1) CPU/Resource intensive but memory cheap objects
                    These type of objects can make the delay long enough for the application
                    to behave badly.

                    2) Logic disorder to user
                    Suppose we're doing a 3D game. A radar is monitoring an target.
                    Obviously, radar should hold a handle or a WeakReference, whatever you like,
                    to the target. If we do not make a determined destruction, then the radar
                    watcher (the gamer) will be quite confused. Is the target destroyed or not?
                    You can not tell him, hey, it's killed but wait for the GC to make it. Sure,
                    you can deploy other methods and logics on the target in order for the radar
                    to determine it's detroyed or not, but that's certainly not as natural as
                    determining it by the condition of whether an object is destructed or not.

                    As a conclusion, I would say it's a serious defect of C#, if there is no way
                    to do stack objects.


                    Comment

                    • Bruce Wood

                      #11
                      Re: Useless Garbage Collection in C#?


                      Born wrote:
                      I've checked WeakReference. It seems a good alternative to handles although
                      my MSDN 2005 says an exception will be triggered if the referenced object
                      has finalized ( I did not experience any exception in my test).
                      This may help... this is how I think of WeakReference.

                      For any object, there are two kinds of references you can hold to it:
                      strong references that require that the object be kept alive in order
                      that the references be useful, and weak references that will use the
                      object if it's available but don't particularly mind if it disappears.
                      Most references are of the first type, strong. Some references,
                      particularly certain types of event subscriptions, are conceptually of
                      the second type.

                      For example, I use weak references to subscribe to static events. I
                      want the object to be notified when, say, the user changes the screen
                      resolution, but I don't particularly care if the event occurs and
                      discovers that the object is gone. Or, from the other angle, it's not
                      worth keeping the object alive just to receive this kind of event.

                      The trick, as Marc pointed out, is to design your program so that every
                      resource has exactly one (strong reference) "owner" at any time, so
                      that it can be disposed when that owner is finished with it. Ownership
                      may pass from one owner to another, but in the end you know whose
                      responsibility it is to dispose of the resource. If you can manage to
                      make every other reference except the owner a "weak reference" then
                      you're done.

                      Sometimes, however, this isn't possible. Sometimes you really do have
                      multiple owners of a resource. In that case you have to implement some
                      sort of reference counting scheme like in C++. The only bummer is that
                      in C# you can't invoke code upon assignment so you can't do auto-magic
                      reference counting. You can do something close, though. You could use a
                      secondary, IDisposable object to hold a reference to your resource,
                      then use "using" to ensure that the reference counting would be correct
                      no matter what. Something like this:

                      public class ReferenceToReso urce : IDisposable
                      {
                      private Resource _res;
                      private bool _disposed = false;

                      public ReferenceToReso urce(Resource res)
                      {
                      this._res = res;
                      res.AddReferenc e();
                      }

                      public void Dispose()
                      {
                      Dispose(true);
                      GC.SuppressFina lize(this);
                      }

                      public virtual void Dispose(bool disposing)
                      {
                      if (!this._dispose d)
                      {
                      if (disposing)
                      {
                      this._res.Remov eReference();
                      }
                      this._disposed = true;
                      }
                      }

                      public Resource Resource
                      {
                      get { return this._res; }
                      }

                      ~ReferenceToRes ource()
                      {
                      Dispose(false);
                      }
                      }

                      I make no claims about the suitability of this code... I just invented
                      it, so it may be buggy! In particular, I was undecided whether to put
                      the this._res.Remov eReference() within the if (disposing) or not. I'm
                      pretty sure it belongs there, but I'm open to being corrected.

                      Once you have this wrapper, you can use it like this:

                      using (ReferenceToRes ource ref = new ReferenceToReso urce(resource))
                      {
                      ... do stuff with "resource" ...
                      }

                      The reference count will be released when leaving the scope of the
                      "using", whether normally or because of an exception.

                      You could also add the ReferenceToReso urce to aggregate structures if
                      you like, or create structures that manage the reference count
                      themselves, automatically.

                      It's not nearly as nice as C++, but fortunately the GC usually makes
                      this sort of thing unnecessary.

                      Comment

                      • Born

                        #12
                        Re: Useless Garbage Collection in C#?


                        Maybe you're not aware of it, but reference counting is GC too ;)
                        Yes, but how can you develop a robust reference counting with C#, in the
                        absense of smart pointer support?

                        Why? I suggest you take a careful look at things such as SafeHandle, and
                        read up on the recommendations on how to wrap resources in .NET, and how
                        to properly implement finalizers etc.
                        See my description on the negative effects caused by Finializers.

                        Can you describe your CPU/resource heavy types a little more? I think
                        that you may be at risk of trying to apply a C++ solution to a general
                        problem.
                        >
                        Resource heavy objects are common: objects holding file handle, network
                        connection and so on.
                        CPU heavy objects refer to those who have internal threads running.

                        Both of these objects can be memory cheap, of course.

                        You could try working with some IDisposable pattern, and ask that users
                        use 'using' statements to protect the resources.
                        >
                        Yes, 'using' it's the only way I found robust. However, it's rather ugly in
                        syntax, if you have experience with Smart Pointers.

                        Born


                        Comment

                        • Born

                          #13
                          Re: Useless Garbage Collection in C#?

                          >
                          It's not nearly as nice as C++, but fortunately the GC usually makes
                          this sort of thing unnecessary.
                          >

                          As I have mentioned, "using" becomes the only way I found robust till now.
                          However, it's not "nearly as nice as C++", it's far from as nice as C++.
                          Reasons:

                          1) Ugly syntax. Please compare smart pointers.
                          2) Not safe. Some of us may forget to use it.
                          3) Not correct by itself. Imagine a ReferenceToReso urce as a variable
                          member. "Using" does not help. The only way is to ask the user to call
                          Dispose of every such member in the host class's Dispose.

                          Moreover, it's not good to say GC usually makes this sort thing unnecessary.
                          It hurts the usage consistency. Suppose you are providing a library or
                          framework, it's really bad to tell your customer to use ReferenceToReso urce
                          on this and not on that. Moreover, there is more potential risk. Suppose a
                          ReferenceToReso urce object as a variable member of a non-ReferenceToReso urce
                          class, then the trick immediately becomes invalid.



                          Comment

                          • Kürþat

                            #14
                            Re: Useless Garbage Collection in C#?

                            Hi,
                            Not all programming languages solve problems as good as others do and tricky
                            solutions -generally- introduce bugs or unhandled situations. If you want to
                            drive C# on C++ s way I am sure you can do. But if you have two different
                            type of gun to shoot, I think you should select most proper one for your
                            game rather than to try to use one's bullet on another.

                            "Born" <wandertop@dlct ek.comwrote in message
                            news:eoksds$suf $1@news.yaako.c om...
                            >
                            >>
                            >It's not nearly as nice as C++, but fortunately the GC usually makes
                            >this sort of thing unnecessary.
                            >>
                            >
                            >
                            As I have mentioned, "using" becomes the only way I found robust till now.
                            However, it's not "nearly as nice as C++", it's far from as nice as C++.
                            Reasons:
                            >
                            1) Ugly syntax. Please compare smart pointers.
                            2) Not safe. Some of us may forget to use it.
                            3) Not correct by itself. Imagine a ReferenceToReso urce as a variable
                            member. "Using" does not help. The only way is to ask the user to call
                            Dispose of every such member in the host class's Dispose.
                            >
                            Moreover, it's not good to say GC usually makes this sort thing
                            unnecessary. It hurts the usage consistency. Suppose you are providing a
                            library or framework, it's really bad to tell your customer to use
                            ReferenceToReso urce on this and not on that. Moreover, there is more
                            potential risk. Suppose a ReferenceToReso urce object as a variable member
                            of a non-ReferenceToReso urce class, then the trick immediately becomes
                            invalid.
                            >
                            >
                            >

                            Comment

                            • Michael D. Ober

                              #15
                              Re: Useless Garbage Collection in C#?

                              You are completely missing the point of a garbage collector. Implement the
                              IDisposable interface and model, which tells the runtime that you have to
                              specifically deallocate resources of some sort. Put your cleanup routines
                              in the IDisposable routines and don't worry about it. If you must control,
                              in code, the cleanup timing, implement a Close method that simply calls your
                              IDisposable interface that handles the actual cleanup an then either use the
                              C# using block or the following try catch finally technique:

                              myClass ClassObject = null;
                              try {
                              ClassObject.Ope n
                              // Processing
                              } catch (Exception ex) {
                              // error handler
                              } finally {
                              ClassObject.Clo se()
                              }

                              Mike.


                              "Born" <wandertop@dlct ek.comwrote in message
                              news:eokgsj$bf6 $1@news.yaako.c om...
                              >
                              >The user should not be absolutely required to use it. If the user
                              >forgets
                              >to Dispose, put the cleanup in the Finalizer. To prevent the Finalizer
                              >from running in case the user do remember to Dispose, use
                              >GC.SuppressFin alize in the Dispose method.
                              >>
                              >
                              If you depend on Finalizer, then there will be a delay between the wanted
                              destroy and the actual destruction. There are two bad effects for it:
                              >
                              1) CPU/Resource intensive but memory cheap objects
                              These type of objects can make the delay long enough for the
                              application to behave badly.
                              >
                              2) Logic disorder to user
                              Suppose we're doing a 3D game. A radar is monitoring an target.
                              Obviously, radar should hold a handle or a WeakReference, whatever you
                              like, to the target. If we do not make a determined destruction, then the
                              radar watcher (the gamer) will be quite confused. Is the target destroyed
                              or not? You can not tell him, hey, it's killed but wait for the GC to make
                              it. Sure, you can deploy other methods and logics on the target in order
                              for the radar to determine it's detroyed or not, but that's certainly not
                              as natural as determining it by the condition of whether an object is
                              destructed or not.
                              >
                              As a conclusion, I would say it's a serious defect of C#, if there is no
                              way to do stack objects.
                              >
                              >

                              Comment

                              Working...