"forcing" garbage collection

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

    "forcing" garbage collection

    I'm trying to wrap my ming around C#/CLR garbage collection. In an
    ASP.NET project, I'm having a problem because an object destructor is
    being called by another thread, long after my code is done. I'm wanting
    to know if I can force it to happen immediately (when the object goes
    out of scope) without going back and adding all of the required
    Dispose() calls..

    public Method()
    {
    CustomClass o = new CustomClass(..) ;
    ..
    ..
    ..
    };

    Is there a way to "force" the CustomClass destructor to be called right
    when the object goes out of scope, by the same thread as the Method?

    Thanks.
  • Peter Duniho

    #2
    Re: "forcing&q uot; garbage collection

    On Mon, 26 May 2008 16:31:20 -0700, Jon Mcleod <jonmcleod2003@ yahoo.com>
    wrote:
    I'm trying to wrap my ming around C#/CLR garbage collection. In an
    ASP.NET project, I'm having a problem because an object destructor is
    being called by another thread, long after my code is done. I'm wanting
    to know if I can force it to happen immediately (when the object goes
    out of scope) without going back and adding all of the required
    Dispose() calls..
    There is a way.

    But the right way to solve this issue is to call Dispose(). Either use
    the "using" statement (preferable), or call Dispose() explicitly.

    Don't fix buggy code by adding more bugs. If that means having to go back
    and rewrite a bunch of code that wasn't dispoing of things properly, so be
    it.

    Pete

    Comment

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

      #3
      Re: &quot;forcing&q uot; garbage collection

      Jon Mcleod wrote:
      I'm trying to wrap my ming around C#/CLR garbage collection. In an
      ASP.NET project, I'm having a problem because an object destructor
      destructor = finalizer ?
      is
      being called by another thread,
      Some code explicit calling a finalizer ?
      long after my code is done. I'm wanting
      to know if I can force it to happen immediately (when the object goes
      out of scope)
      Making an explicit call ? Or an implicit call ? And what about the
      reference in the other thread ?
      without going back and adding all of the required
      Dispose() calls..
      >
      public Method()
      {
      CustomClass o = new CustomClass(..) ;
      ..
      ..
      ..
      };
      >
      Is there a way to "force" the CustomClass destructor to be called right
      when the object goes out of scope, by the same thread as the Method?
      Dispose is for unmanaged resources.

      Garbage collection is for managed resources.

      If the object only holds managed resources then let the GC do
      what it wants to do when it want to do it.

      If the object holds unmanaged resources then use the
      Dispose pattern.

      Arne



      Comment

      • Michael D. Ober

        #4
        Re: &quot;forcing&q uot; garbage collection

        "Arne Vajhøj" <arne@vajhoej.d kwrote in message
        news:483b534a$0 $90271$14726298 @news.sunsite.d k...
        Jon Mcleod wrote:
        >I'm trying to wrap my ming around C#/CLR garbage collection. In an
        >ASP.NET project, I'm having a problem because an object destructor
        >
        destructor = finalizer ?
        >
        > is
        >being called by another thread,
        >
        Some code explicit calling a finalizer ?
        >
        > long after my code is done. I'm wanting
        >to know if I can force it to happen immediately (when the object goes out
        >of scope)
        >
        Making an explicit call ? Or an implicit call ? And what about the
        reference in the other thread ?
        >
        > without going back and adding all of the required
        >Dispose() calls..
        >>
        > public Method()
        > {
        > CustomClass o = new CustomClass(..) ;
        > ..
        > ..
        > ..
        > };
        >>
        >Is there a way to "force" the CustomClass destructor to be called right
        >when the object goes out of scope, by the same thread as the Method?
        >
        Dispose is for unmanaged resources.
        >
        Garbage collection is for managed resources.
        >
        If the object only holds managed resources then let the GC do
        what it wants to do when it want to do it.
        >
        If the object holds unmanaged resources then use the
        Dispose pattern.
        >
        Arne
        >
        Dispose is also useful when the "managed" resource is actually an OS
        resource such as a socket. In this case explicitly disposing the socket
        frees up OS resources on two different machines.

        Mike.


        Comment

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

          #5
          Re: &quot;forcing&q uot; garbage collection

          Michael D. Ober wrote:
          "Arne Vajhøj" <arne@vajhoej.d kwrote in message
          news:483b534a$0 $90271$14726298 @news.sunsite.d k...
          >Jon Mcleod wrote:
          >>I'm trying to wrap my ming around C#/CLR garbage collection. In an
          >>ASP.NET project, I'm having a problem because an object destructor
          >>
          >destructor = finalizer ?
          >>
          >> is
          >>being called by another thread,
          >>
          >Some code explicit calling a finalizer ?
          >>
          >> long after my code is done. I'm
          >>wanting to know if I can force it to happen immediately (when the
          >>object goes out of scope)
          >>
          >Making an explicit call ? Or an implicit call ? And what about the
          >reference in the other thread ?
          >>
          >> without going back and adding all of the required
          >>Dispose() calls..
          >>>
          >> public Method()
          >> {
          >> CustomClass o = new CustomClass(..) ;
          >> ..
          >> ..
          >> ..
          >> };
          >>>
          >>Is there a way to "force" the CustomClass destructor to be called
          >>right when the object goes out of scope, by the same thread as the
          >>Method?
          >>
          >Dispose is for unmanaged resources.
          >>
          >Garbage collection is for managed resources.
          >>
          >If the object only holds managed resources then let the GC do
          >what it wants to do when it want to do it.
          >>
          >If the object holds unmanaged resources then use the
          >Dispose pattern.
          >
          Dispose is also useful when the "managed" resource is actually an OS
          resource such as a socket. In this case explicitly disposing the socket
          frees up OS resources on two different machines.
          I would have assumed that sockets somewhere deep down contained
          unmanaged resources.

          Arne

          Comment

          • Peter Duniho

            #6
            Re: &quot;forcing&q uot; garbage collection

            On Mon, 26 May 2008 18:06:05 -0700, Michael D. Ober
            <obermd.@.alum. mit.edu.nospam. wrote:
            Dispose is also useful when the "managed" resource is actually an OS
            resource such as a socket. In this case explicitly disposing the socket
            frees up OS resources on two different machines.
            As Arne says, the OS resource _is_ unmanaged. As for "on two different
            machines", disposing your Socket instance locally does nothing one way or
            the other with respect to freeing up a similar unmanaged resource on the
            remote endpoint computer. That's up to the implementation on the other
            end.

            Pete

            Comment

            • Jon Mcleod

              #7
              Re: &quot;forcing&q uot; garbage collection

              Michael D. Ober wrote:
              >
              Dispose is also useful when the "managed" resource is actually an OS
              resource such as a socket. In this case explicitly disposing the socket
              frees up OS resources on two different machines.
              >
              In this case, the object is a managed object but it contains a database
              connection. This is an ASP.NET project, and there are two problems.
              First, these objects are being left alive for quite some time, causing
              the site to start artificially running out of database connections after
              running a while. Secondly, GC happens on its own thread, causing a
              "Internal .Net Framework Data Provider error 1." when it calls Close on
              the the apparently single-threaded SqlConnection object.

              My solution right now it to use IDisposed to explicitly manage the
              lifetime of these objects, to sidestep the whole issue. I don't have a
              lot of experience with these technologies, though. Is there a better way?

              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: &quot;forcing&q uot; garbage collection

                On May 27, 12:00 pm, Jon Mcleod <jonmcleod2...@ yahoo.comwrote:
                Dispose is also useful when the "managed" resource is actually an OS
                resource such as a socket. In this case explicitly disposing the socket
                frees up OS resources on two different machines.
                >
                In this case, the object is a managed object but it contains a database
                connection. This is an ASP.NET project, and there are two problems.
                First, these objects are being left alive for quite some time, causing
                the site to start artificially running out of database connections after
                running a while. Secondly, GC happens on its own thread, causing a
                "Internal .Net Framework Data Provider error 1." when it calls Close on
                the the apparently single-threaded SqlConnection object.
                >
                My solution right now it to use IDisposed to explicitly manage the
                lifetime of these objects, to sidestep the whole issue. I don't have a
                lot of experience with these technologies, though. Is there a better way?
                Disposing of the objects sounds like absolutely the right way to go.
                However, in my experience it's almost always a bad idea to keep a
                database connection alive in an object anyway. I find it's almost
                always better to create the connection for the duration of the
                database call, then close it. Connection pooling ensures efficiency of
                physical connections, and you get away from a lot of the resource
                issues it sounds like you're facing.

                Jon

                Comment

                • Michael D. Ober

                  #9
                  Re: &quot;forcing&q uot; garbage collection

                  "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
                  news:op.ubsslgl 48jd0ej@petes-computer.local. ..
                  On Mon, 26 May 2008 18:06:05 -0700, Michael D. Ober
                  <obermd.@.alum. mit.edu.nospam. wrote:
                  >
                  >Dispose is also useful when the "managed" resource is actually an OS
                  >resource such as a socket. In this case explicitly disposing the socket
                  >frees up OS resources on two different machines.
                  >
                  As Arne says, the OS resource _is_ unmanaged. As for "on two different
                  machines", disposing your Socket instance locally does nothing one way or
                  the other with respect to freeing up a similar unmanaged resource on the
                  remote endpoint computer. That's up to the implementation on the other
                  end.
                  >
                  Pete
                  >

                  First, at some point every non-memory resource in dotNET is a OS resource
                  and closing it when done is a good thing to do. dotNET is very good at
                  reusing resources via pooling but Windows itself isn't, so using the dispose
                  pattern on just about any class that you use and/or create is a good idea
                  simply from the perspective of being nice to other applications on the
                  system. Second, most decent servers watch for and handle closed distant end
                  (client or server) sockets by closing a socket when a processing a zero byte
                  read. This is part of the Berkeley standard for socket communications.
                  Again, closing the non-memory resource via dispose is a good idea so that
                  any other systems involved in that resource are notified that they can close
                  their resources.

                  The real problem on whether or not to use dispose is that the framework has
                  blurred the lines between managed and unmanaged. For someone who has never
                  written to the underlying OS, the fact that a lot of the framework classes
                  contains a Dispose method really doesn't have any meaning because the
                  non-memory OS resource is "hidden" from them. Yes, if you don't explicitly
                  call obj.Dispose or use the "using" design pattern the framework will
                  eventually call Dispose and release the underlying resource, but this isn't
                  necessarily a good way of doing this.

                  Mike.


                  Comment

                  • Peter Duniho

                    #10
                    Re: &quot;forcing&q uot; garbage collection

                    On Tue, 27 May 2008 16:40:51 -0700, Michael D. Ober
                    <obermd.@.alum. mit.edu.nospam. wrote:
                    First, at some point every non-memory resource in dotNET is a OS
                    resource and closing it when done is a good thing to do.
                    No one's suggested otherwise. Keep in mind, of course, that you are
                    confusing "close" with "dispose". It's true that many classes offer both,
                    and in many of those cases, the call to Close() does practically or
                    exactly the same thing as calling Dispose(). But they are two distinct
                    operations. It's a mistake to refer to one as if it's synonymous with the
                    other.
                    dotNET is very good at reusing resources via pooling but Windows itself
                    isn't,
                    ..NET doesn't do any pooling, except in very specific, documented
                    scenarios. Even in the classes that implement pooling, you need to
                    release the resource being used so that it can be returned to the pool.
                    In at least one case, this involves calling Close() or Dispose() (in that
                    particular case, the two are equivalent).

                    I'm not really sure what point you're trying to make, but if you're saying
                    that one can rely on resource pooling from .NET as an alternative to
                    calling Close() or Dispose(), that's a very misleading and incorrect
                    implication to make.
                    so using the dispose pattern on just about any class that you use and/or
                    create is a good idea simply from the perspective of being nice to other
                    applications on the system.
                    In many cases, the application that is most critically affected by whether
                    you Close() or Dispose() a class is your own. It's not just a matter of
                    "being nice".
                    Second, most decent servers watch for and handle closed distant end
                    (client or server) sockets by closing a socket when a processing a zero
                    byte read. This is part of the Berkeley standard for socket
                    communications.
                    You are confusing the question of resource disposal and network API. The
                    socket comparison is apt for illustrating this, ironically enough. In BSD
                    terminology: a TCP socket uses shutdown() to initiate a graceful closure.
                    When you do this, the underlying TCP is eventually closed (including a
                    zero-byte receive at the other end), but the socket resource still lives
                    on. Not until you call closesocket() is the actual socket cleaned up, but
                    assuming a graceful closure, the remote endpoint has already been notified
                    of the closure of the connection (and may have itself already disposed its
                    own resources), even without disposal of the local resource.

                    (In .NET, this corresponds closely to the Socket.Shutdown () and
                    Socket.Close() methods).

                    Conversely, even if you reset a connection ungracefully (by calling
                    closesocket() without shutdown()), there is _nothing_ that guarantees that
                    the remote endpoint will even detect that correctly, never mind will clean
                    up its own resources. Resource management at the other end is _entirely_
                    up to the code running on that end.

                    It is a serious mistake to say that resource management within one's own
                    application is done for the sake of code running elsewhere. There are in
                    fact aspects of a network API (for example) that require considerate
                    behavior so that the other end can more effectively manage its own
                    resources, but these aspects are entirely independent of the question of
                    local resource management. Instead, they are part of the
                    application-level protocol that defines the interaction of the
                    applications, and this application-level protocol has nothing to do with
                    the underlying implementation.
                    Again, closing the non-memory resource via dispose is a good idea so
                    that any other systems involved in that resource are notified that they
                    can close their resources.
                    It's a good idea, but not for the reason you state.
                    The real problem on whether or not to use dispose is that the framework
                    has blurred the lines between managed and unmanaged. For someone who has
                    never written to the underlying OS, the fact that a lot of the framework
                    classes contains a Dispose method really doesn't have any meaning
                    because the non-memory OS resource is "hidden" from them.
                    If you are relying on whether a class implements IDisposable to tell you
                    whether it includes unmanaged resources, then yes...I can see your
                    confusion. But that's because IDisposable doesn't tell you that at all.
                    It's true that a class that includes unmanaged resources really needs to
                    implement IDisposable, but it's not necessarily the case that IDisposable
                    means there are unmanaged resources being used.

                    What you really should be taking away from the IDisposable issue is that
                    as a .NET programmer, you really shouldn't be worrying about whether some
                    other class uses unmanaged resources. If the class implements
                    IDisposable, you should call Dispose() when you're done with it, period.
                    Not because it might use unmanaged resources (though it very well might),
                    but because that's the contract defined by the class's API.

                    The "unmanaged/managed" question is really just a red herring. It's made
                    worse by your inaccurate claim that calling Dispose() is an effective and
                    correct way to manage an inter-process communication API (as in your
                    networking example).
                    Yes, if you don't explicitly call obj.Dispose or use the "using" design
                    pattern the framework will eventually call Dispose and release the
                    underlying resource, but this isn't necessarily a good way of doing this.
                    That's certainly true.

                    I'm sorry if it seems like I'm nitpicking, but IMHO it's very important to
                    get these details right. People synthesize new ideas from what they
                    believe they already know, and so even if from a practical sense, your
                    inaccuracies don't have any direct effect on a particular implementation,
                    feeding people bogus information can lead them to make unforeseen
                    erroneous decisions in the future. Anyone who treats IDisposable as part
                    of a protocol management strategy for inter-process communications is
                    eventually going to be write some code that doesn't do what they think it
                    does, introducing one or more bugs that are potentially difficult to find
                    and fix.

                    Pete

                    Comment

                    • =?UTF-8?B?QXJuZSBWYWpow7hq?=

                      #11
                      Re: &quot;forcing&q uot; garbage collection

                      First, at some point every non-memory resource in dotNET is a OS
                      resource and closing it when done is a good thing to do.
                      Yes !

                      So Close/Dispose those.
                      The real problem on whether or not to use dispose is that the framework
                      has blurred the lines between managed and unmanaged. For someone who
                      has never written to the underlying OS, the fact that a lot of the
                      framework classes contains a Dispose method really doesn't have any
                      meaning because the non-memory OS resource is "hidden" from them.
                      If something implements IDisposable, then you can just call Dispose.

                      If it is a no-op then the overhead is very small.

                      Better safe than sorry.

                      Arne

                      Comment

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

                        #12
                        Re: &quot;forcing&q uot; garbage collection

                        Jon Mcleod wrote:
                        In this case, the object is a managed object but it contains a database
                        connection. This is an ASP.NET project, and there are two problems.
                        First, these objects are being left alive for quite some time, causing
                        the site to start artificially running out of database connections after
                        running a while. Secondly, GC happens on its own thread, causing a
                        "Internal .Net Framework Data Provider error 1." when it calls Close on
                        the the apparently single-threaded SqlConnection object.
                        >
                        My solution right now it to use IDisposed to explicitly manage the
                        lifetime of these objects, to sidestep the whole issue. I don't have a
                        lot of experience with these technologies, though. Is there a better way?
                        database =call Close or Dispose

                        If not then you will get problems !

                        Arne

                        Comment

                        Working...