Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. This is why I am starting to loathe programming

This is why I am starting to loathe programming

Scheduled Pinned Locked Moved The Lounge
phpvisual-studiocom
82 Posts 31 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Fabio Franco

    Hi Gerardo, I know that GC can't be predicted, however you can force a collection with GC.Collect() Garbage Collection is no guarantee that Dispose gets called, it all depends on the finalizer implementation. If Dispose correctly releases unmanaged resources and if you call it from the finalizer (good code), then yes, unmanaged resource will be released when a collection occurs, if you don't, Dispose method will never get called and the unmanaged resources will never be reclaimed (not until the process ends). In another discussion in this topic I provide an example of exactly that, where the Window handle is not released even after forcing collection (finalizer gets called, you can see it throug output windows). Only way it did was through explicitly calling Dispose method afer the form was closed, inside the calling method. Regards, Fábio

    S Offline
    S Offline
    sgorozco
    wrote on last edited by
    #64

    Hi Fabio, Yes, you are correct, good code should follow the IDisposable pattern documented by Microsoft, that way you can dispose unmanaged resources early if you want, or leave it to the GC. I'll look at your example, because if what you say is true, then Microsoft is not following its own recommended patterns! Thanks for the reply, Gerardo

    F 1 Reply Last reply
    0
    • S sgorozco

      Hi Fabio, Yes, you are correct, good code should follow the IDisposable pattern documented by Microsoft, that way you can dispose unmanaged resources early if you want, or leave it to the GC. I'll look at your example, because if what you say is true, then Microsoft is not following its own recommended patterns! Thanks for the reply, Gerardo

      F Offline
      F Offline
      Fabio Franco
      wrote on last edited by
      #65

      Thanks Gerardo, yes the point was exactly that, and I prefer not to rely on the Finalizer implementation, simply call Dispose and play the safe side.

      1 Reply Last reply
      0
      • F Fabio Franco

        Andrew Rissing wrote:

        It's likely the extra handle is for a Font or Image that is statically allocated, but only done so once it was loaded. So, I wouldn't call that a leak. It is evident by the fact that the object is being disposed and/or finalized, but the overall count is not going up (minus the initial value).

        Ok, but why does the count comes down when the form's Dispose method is called from the calling method, and not from the finalizer? I mean if it is something static, it should not come down either way right? This is what's boggling me. Thank you for your clarifications, it surely filled a few gaps. Still, there is this thing, bothering me... Did you get to reproduce what I was saying?

        A Offline
        A Offline
        Andrew Rissing
        wrote on last edited by
        #66

        Indeed, I was able to reproduct it. I don't know though if its a memory leak or just something else we aren't aware of. If it was a true memory leak, I would imagine that it's behavior would be repeatable and the allocations would keep rising. Ultimately, one handle is pretty insignificant in the grand scheme of things.

        F 1 Reply Last reply
        0
        • A Andrew Rissing

          Indeed, I was able to reproduct it. I don't know though if its a memory leak or just something else we aren't aware of. If it was a true memory leak, I would imagine that it's behavior would be repeatable and the allocations would keep rising. Ultimately, one handle is pretty insignificant in the grand scheme of things.

          F Offline
          F Offline
          Fabio Franco
          wrote on last edited by
          #67

          Yes, this keeps me thinking that this is just one case, for one form. What else might have this behaviour? and depending on the scenario, this might rise significantly. So I have no doubt that calling Dispose (when you desire to release resources of course) is a very strong should, no matter how the Garbage Collector gets invoked. One theory I have about this behaviour is that one of these handles is kept for performance issues. When Dispose does not get called and the object is collected, the Garbage Collector (or the Finalizer / IDisposable implementation) might think it will be reused (instatiated again at some point of time) and so the handle is kept for reuse with the same form. If you experiment a little more, you'll also notice that another handle increment will happen if you instatiate another Form implementation (besides from TestForm) and don't call Dispose. Same thing will happen for that form. Anyways, this was a nice discussion to have. Regards, Fábio

          A 1 Reply Last reply
          0
          • L leppie

            It's like the blind leading the blind.... http://stackoverflow.com/questions/2926869/c-do-you-need-to-dispose-of-objects-and-set-them-to-null/2926877#2926877[^] I think I will get similar responses from here too though :sigh:

            xacc.ide
            IronScheme - 1.0 RC 1 - out now!
            ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

            B Offline
            B Offline
            bjarneds
            wrote on last edited by
            #68

            Looking at all the responses in this thread, there seem to be a lot of confusion about dispose and finalization. The basic recommendations is really not that complicated :-\ : 1) In the finalizer (i.e. ~SomeClass() ), clean up unmanaged resources. This method is called by the garbage collector, when the object can no longer be reached. However, it may not happen immediately, the garbage collector waits until it needs memory (which could be hours or days after it is no longer reachable). 2) In Dispose() (i.e. the method defined in IDisposable), cleanup managed and unmanaged resources. Furthermore, call GC.SuppressFinalize(this) (since everything is now cleaned up, there is no need for the finalizer to be called by the garbage collector, and doing this optimizes the garbage collection). The dispose pattern furthermore combines the implementation of these two, by implementing a protected Dispose(bool disposing) in the base class. The finalizer calls it with false, the Dispose() in IDisposable calls it with true. This makes it simple for derived classes, it only has to override this method and add whatever it needs, but it doesn't really change anything, it just a matter of style in the implementation. Why shouldn't the finalizer clean up managed resources as well? Because that is what the garbage collector does - managed resources is the memory used by other managed classes. Furthermore, it is very limited what a finalizer is allowed to do - it must not use references to other objects (as they may already be garbage collected). Why implement Dispose(), if the garbage collector takes care of it all? Because sometimes you need some cleanup to take place at a deterministic time, not hours or days later. The classical example is an open file. You typically want to allow the file being opened again, immediately you are done using it. Why do you need IDisposable for this, why not just implement a Close method on the class? Because with IDisposable, you have a uniform way of dealing with scenarios like this (e.g. a using block). You are free to implement a Close method as well if it feels more natural to use this name - this would simply call Dispose(). Are there any other reasons for Dispose() than deterministic cleanup (or: are there any situations where you have to call Dispose())? Yes (and this is where it gets a little more complicated :doh: ). If the object you no longer need is referenced by a longer living object, it may unintentionally keep it alive. Y

            C 1 Reply Last reply
            0
            • C CurtainDog

              If the class creator wants it to be used in a particular way then they can build a factory for it. Up until that point I'll use the class however I want to.

              P Offline
              P Offline
              peterchen
              wrote on last edited by
              #69

              Welcome to not my team.

              Agh! Reality! My Archnemesis![^]
              | FoldWithUs! | sighist | µLaunch - program launcher for server core and hyper-v server.

              1 Reply Last reply
              0
              • A AspDotNetDev

                Some people in the C# forum once informed me that not using "using" could lead to memory leaks due to the way .Net manages memory. They say that, because unmanaged resources are outside of the memory tracked by .Net, that memory can grow very large without triggering a garbage collection by .Net. So, maybe you have some objects with finalizers and such that make it the least often collected object. And maybe you only have a few of them and they don't take up much managed memory in .Net. However, they could still reference a ton of unmanaged memory, and .Net does not count that large amount of unmanaged memory when deciding whether or not to perform a garbage collection. That can lead to the memory growing out of hand... perhaps too far out of hand before .Net decides to do a garbage collection. Not sure if that's correct, but that's about what I think they were trying to convey to me.

                [Forum Guidelines]

                B Offline
                B Offline
                Bradley Smith Belly G
                wrote on last edited by
                #70

                Thats the exact situation that is found when using the sharepoint 2007 object model - there are .net wrappers around the unmanaged sharepoint code base, which leads .net to think there is only a small amount of memory used, when 5MB is actually used for each object! So every time you end up accessing a site your memory grows... until it dies.... :laugh:

                1 Reply Last reply
                0
                • L leppie

                  Daniel Grunwald wrote:

                  But it does lead to excessive resource usage and potentially even to resource exhaustion (where resource != memory).

                  That was my point too.

                  Daniel Grunwald wrote:

                  It's a bad idea to not dispose IDisposable objects.

                  I know you should, but you dont have to, unless you want it to be deterministic.

                  xacc.ide
                  IronScheme - 1.0 RC 1 - out now!
                  ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

                  Y Offline
                  Y Offline
                  Yortw
                  wrote on last edited by
                  #71

                  ...and sometimes it's really important to be deterministic, such as with files, serial ports (or any hardware port probably), and sockets... otherwise a future attempt to re-open the same item may fail because the resource is locked by an uncollected out of scope object that wasn't disposed. Yes, dispose can help with memory clean up, but more importantly (in some cases) it releases locks on scarce resources. True also of database connections to a point... I have seen web apps that do not correctly dispose database connections and eventually fail because the 'connection pool is full'... many of the connections aren't active, but they haven't been returned to the pool because there's some number of .Net SqlConnection objects still undisposed in memory.

                  1 Reply Last reply
                  0
                  • B bjarneds

                    Looking at all the responses in this thread, there seem to be a lot of confusion about dispose and finalization. The basic recommendations is really not that complicated :-\ : 1) In the finalizer (i.e. ~SomeClass() ), clean up unmanaged resources. This method is called by the garbage collector, when the object can no longer be reached. However, it may not happen immediately, the garbage collector waits until it needs memory (which could be hours or days after it is no longer reachable). 2) In Dispose() (i.e. the method defined in IDisposable), cleanup managed and unmanaged resources. Furthermore, call GC.SuppressFinalize(this) (since everything is now cleaned up, there is no need for the finalizer to be called by the garbage collector, and doing this optimizes the garbage collection). The dispose pattern furthermore combines the implementation of these two, by implementing a protected Dispose(bool disposing) in the base class. The finalizer calls it with false, the Dispose() in IDisposable calls it with true. This makes it simple for derived classes, it only has to override this method and add whatever it needs, but it doesn't really change anything, it just a matter of style in the implementation. Why shouldn't the finalizer clean up managed resources as well? Because that is what the garbage collector does - managed resources is the memory used by other managed classes. Furthermore, it is very limited what a finalizer is allowed to do - it must not use references to other objects (as they may already be garbage collected). Why implement Dispose(), if the garbage collector takes care of it all? Because sometimes you need some cleanup to take place at a deterministic time, not hours or days later. The classical example is an open file. You typically want to allow the file being opened again, immediately you are done using it. Why do you need IDisposable for this, why not just implement a Close method on the class? Because with IDisposable, you have a uniform way of dealing with scenarios like this (e.g. a using block). You are free to implement a Close method as well if it feels more natural to use this name - this would simply call Dispose(). Are there any other reasons for Dispose() than deterministic cleanup (or: are there any situations where you have to call Dispose())? Yes (and this is where it gets a little more complicated :doh: ). If the object you no longer need is referenced by a longer living object, it may unintentionally keep it alive. Y

                    C Offline
                    C Offline
                    CurtainDog
                    wrote on last edited by
                    #72

                    bjarneds wrote:

                    In previous versions of .NET, this problem could be illustrated simply by adding e.g. a DateTimePicker to Form2. The DateTimePicker subscribed to the UserPreferenceChangedEvent, so it was kept alive, and it's Parent reference to Form2 thus kept Form2 alive. This is not the case in .NET 3.5 - maybe they changed the design, or used some sort of weak reference?

                    So if the event used a weak reference instead the problem would go away?

                    B 1 Reply Last reply
                    0
                    • F Fabio Franco

                      Yes, this keeps me thinking that this is just one case, for one form. What else might have this behaviour? and depending on the scenario, this might rise significantly. So I have no doubt that calling Dispose (when you desire to release resources of course) is a very strong should, no matter how the Garbage Collector gets invoked. One theory I have about this behaviour is that one of these handles is kept for performance issues. When Dispose does not get called and the object is collected, the Garbage Collector (or the Finalizer / IDisposable implementation) might think it will be reused (instatiated again at some point of time) and so the handle is kept for reuse with the same form. If you experiment a little more, you'll also notice that another handle increment will happen if you instatiate another Form implementation (besides from TestForm) and don't call Dispose. Same thing will happen for that form. Anyways, this was a nice discussion to have. Regards, Fábio

                      A Offline
                      A Offline
                      Andrew Rissing
                      wrote on last edited by
                      #73

                      Indeed that is probably a good explaination. It's kind of hard to tell sometimes what they're doing under the hood.

                      F 1 Reply Last reply
                      0
                      • D Daniel Grunwald

                        Incorrect. IDisposable clearly is a contract with the user of the object. It's that user who is supposed to call Dispose() (granted, it's not a must call, but usually it's seen as should call). The GC isn't interested in IDisposable at all, it only cares about finalizers. It's perfectly reasonable to have classes with finalizer that don't implement IDisposable if you don't need deterministic release of your resources. System.WeakReference is an example of a class that has a finalizer but offers no Dispose() or similar method.

                        T Offline
                        T Offline
                        TheGreatAndPowerfulOz
                        wrote on last edited by
                        #74

                        Wrong! User's are *not* necessarily "supposed" to call Dispose(). However, *if* they don't call Dispose(), then the GC will. The only time you *must* do it is when the docs of the class say you *must* do so, like in the situation where a Dispose() wraps a db transaction. Then the typical usage is in a using or try/finally statement.

                        Fight Big Government:
                        http://obamacareclassaction.com/
                        http://obamacaretruth.org/

                        T 1 Reply Last reply
                        0
                        • L leppie

                          The ratio of unmanaged memory to managed memory is pretty much insignificant, in 95%+ cases. Anyways, there are classes to inform the CLR about this, if it is excessive.

                          xacc.ide
                          IronScheme - 1.0 RC 1 - out now!
                          ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

                          M Offline
                          M Offline
                          molesworth
                          wrote on last edited by
                          #75

                          leppie wrote:

                          The ratio of unmanaged memory to managed memory is pretty much insignificant, in 95%+ cases.

                          Ummm, in some application areas (my own included) unmanaged memory usage can be many times larger than the managed classes which are controlling it. Proper use of IDisposable and SafeHandle derived types means better control of memory use and better app stability.

                          Days spent at sea are not deducted from one's alloted span - Phoenician proverb

                          1 Reply Last reply
                          0
                          • V Vikram A Punathambekar

                            PIEBALDconsult wrote:

                            In my opinion, object should have a virtual do-nothing Dispose method so that any class or struct can be used with the using statement. (We would therefore not need the IDisposable interface.)

                            For everybody, not just piebald: it's been well over 1.5 years since I wrote C# production code, so take my words with a large dose of scepticism. I agree with Piebald here. Any gurus care to explain why this isn't the case?

                            Cheers, Vikram. (Got my troika of CCCs!)

                            M Offline
                            M Offline
                            molesworth
                            wrote on last edited by
                            #76

                            I'm no guru, but if I remember correctly what our local gurus have said, deriving from IDisposable is means the object is treated differently by the GC in some way. I could be wrong of course... :)

                            Days spent at sea are not deducted from one's alloted span - Phoenician proverb

                            1 Reply Last reply
                            0
                            • A Andrew Rissing

                              Indeed that is probably a good explaination. It's kind of hard to tell sometimes what they're doing under the hood.

                              F Offline
                              F Offline
                              Fabio Franco
                              wrote on last edited by
                              #77

                              I found this about the Component Class[^], which Form derives from (not directly, but it does). "A Component should release resources explicitly by calls to its Dispose method, without waitin"g for automatic memory management through an implicit call to the Finalize method. When a Container is disposed, all components within the Container are also disposed." It's interesting that if we let the Garbage Collector deal with the form's disposal, we will be doing exactly the opposite as the above recommendation.

                              A 1 Reply Last reply
                              0
                              • C CurtainDog

                                bjarneds wrote:

                                In previous versions of .NET, this problem could be illustrated simply by adding e.g. a DateTimePicker to Form2. The DateTimePicker subscribed to the UserPreferenceChangedEvent, so it was kept alive, and it's Parent reference to Form2 thus kept Form2 alive. This is not the case in .NET 3.5 - maybe they changed the design, or used some sort of weak reference?

                                So if the event used a weak reference instead the problem would go away?

                                B Offline
                                B Offline
                                bjarneds
                                wrote on last edited by
                                #78

                                Yes, I believe so (I don't have practical experience with weak references though). Thinking about it, it may also be possible to solve the problem in this case by subscribing/unsubscribing when visibility of the form changes. But this only works because it is a form/control, because visibility can be used as a replacement for the client (owner form) telling when it is no longer used. In other classes, you may not have this option.

                                1 Reply Last reply
                                0
                                • F Fabio Franco

                                  I found this about the Component Class[^], which Form derives from (not directly, but it does). "A Component should release resources explicitly by calls to its Dispose method, without waitin"g for automatic memory management through an implicit call to the Finalize method. When a Container is disposed, all components within the Container are also disposed." It's interesting that if we let the Garbage Collector deal with the form's disposal, we will be doing exactly the opposite as the above recommendation.

                                  A Offline
                                  A Offline
                                  Andrew Rissing
                                  wrote on last edited by
                                  #79

                                  Indeed, relying on finalize is less efficient than calling dispose on your own, but in a managed environment you need some sort of framework for handling things that don't get disposed of properly.

                                  1 Reply Last reply
                                  0
                                  • T TheGreatAndPowerfulOz

                                    Wrong! User's are *not* necessarily "supposed" to call Dispose(). However, *if* they don't call Dispose(), then the GC will. The only time you *must* do it is when the docs of the class say you *must* do so, like in the situation where a Dispose() wraps a db transaction. Then the typical usage is in a using or try/finally statement.

                                    Fight Big Government:
                                    http://obamacareclassaction.com/
                                    http://obamacaretruth.org/

                                    T Offline
                                    T Offline
                                    Trajan McGill
                                    wrote on last edited by
                                    #80

                                    Where did you get that idea? The GC does not call Dispose() at all. The GC calls the finalizer, which should, on well-designed code, call Dispose(). I'm talking about languages other than C++ here, though, I'm less familiar with how managed C++ integrates into the .NET garbage collection, and it seems to have some differences from C# or VB.NET. This whole discussion thread is a little bit confused. The basics are this: IDisposable is around to allow you to mark your class as one using resources that should be explicitly released upon finishing with an object, and Dispose() exists to provide a way of doing that explicit resource release. Any class where calling Dispose() is not necessary has no reason to implement IDisposable, so we should always treat IDisposable classes as ones on which Dispose() should be called. Some of the confusion arises because people are talking about "memory leaks". That's not really the issue here, at least not memory that is all allocated for managed objects, because the GC will free that up when it needs to. What you can leak, or just as problematically hold onto indefinitely and cause problems, are all sorts of unmanaged things. Mainly these are things which are scarce or should be held as short a time as possible: locks on a file, connections to a database, huge memory-gobbling outside objects, custom objects that do things which need cleaning up to restore the state of unmanaged things, and so on. Things that, if you only dispose of them in a finalizer, will sit around and potentially block other processes or hold onto possibly important resources until the GC gets around to running your finalizer (even assuming your finalizer disposes of them properly, which it should if you wrote it correctly). The GC doesn't even know about these resources, what they are, how important they are, how big they are, so it isn't going to be triggered in any way by the fact that you're running out of whatever those resources are. Therefore, you will use them up with the danger of them not being freed before they run out or need to be re-used. This sort of thing _could_ result in a memory leak, but only because you could be using some kind of unmanaged resource that is in turn making use of memory. In any case, because the whole purpose of putting a Dispose() method on a class is to add, in a case where deterministic disposal of resources is important, the ability to do so, Dispose() should always be explicitly called on classes that implement IDisposable. That is the main r

                                    T 1 Reply Last reply
                                    0
                                    • T Trajan McGill

                                      Where did you get that idea? The GC does not call Dispose() at all. The GC calls the finalizer, which should, on well-designed code, call Dispose(). I'm talking about languages other than C++ here, though, I'm less familiar with how managed C++ integrates into the .NET garbage collection, and it seems to have some differences from C# or VB.NET. This whole discussion thread is a little bit confused. The basics are this: IDisposable is around to allow you to mark your class as one using resources that should be explicitly released upon finishing with an object, and Dispose() exists to provide a way of doing that explicit resource release. Any class where calling Dispose() is not necessary has no reason to implement IDisposable, so we should always treat IDisposable classes as ones on which Dispose() should be called. Some of the confusion arises because people are talking about "memory leaks". That's not really the issue here, at least not memory that is all allocated for managed objects, because the GC will free that up when it needs to. What you can leak, or just as problematically hold onto indefinitely and cause problems, are all sorts of unmanaged things. Mainly these are things which are scarce or should be held as short a time as possible: locks on a file, connections to a database, huge memory-gobbling outside objects, custom objects that do things which need cleaning up to restore the state of unmanaged things, and so on. Things that, if you only dispose of them in a finalizer, will sit around and potentially block other processes or hold onto possibly important resources until the GC gets around to running your finalizer (even assuming your finalizer disposes of them properly, which it should if you wrote it correctly). The GC doesn't even know about these resources, what they are, how important they are, how big they are, so it isn't going to be triggered in any way by the fact that you're running out of whatever those resources are. Therefore, you will use them up with the danger of them not being freed before they run out or need to be re-used. This sort of thing _could_ result in a memory leak, but only because you could be using some kind of unmanaged resource that is in turn making use of memory. In any case, because the whole purpose of putting a Dispose() method on a class is to add, in a case where deterministic disposal of resources is important, the ability to do so, Dispose() should always be explicitly called on classes that implement IDisposable. That is the main r

                                      T Offline
                                      T Offline
                                      TheGreatAndPowerfulOz
                                      wrote on last edited by
                                      #81

                                      and guess what? the default finalizer calls dispose if the class implements IDisposable. So, yeah, indirectly the GC calls Dispose().

                                      Fight Big Government:
                                      http://obamacareclassaction.com/
                                      http://obamacaretruth.org/

                                      T 1 Reply Last reply
                                      0
                                      • T TheGreatAndPowerfulOz

                                        and guess what? the default finalizer calls dispose if the class implements IDisposable. So, yeah, indirectly the GC calls Dispose().

                                        Fight Big Government:
                                        http://obamacareclassaction.com/
                                        http://obamacaretruth.org/

                                        T Offline
                                        T Offline
                                        Trajan McGill
                                        wrote on last edited by
                                        #82

                                        And that's simply incorrect. There is no default finalizer. If you're implementing an IDisposable class, you should make one, and you should have it call your own Dispose() function. Here is a helpful line from MSDN documentation, which confirms both points, that Dispose() is not called automatically and that you have to make your own finalizer and should use it to call Dispose() or do what Dispose() does, lest the GC free up your object without releasing its unmanaged resources: "Because the Dispose method must be called explicitly, objects that implement IDisposable must also implement a finalizer to handle freeing resources when Dispose is not called." You may reference http://msdn.microsoft.com/en-us/library/system.idisposable.dispose%28VS.71%29.aspx[^] for more on the subject.

                                        1 Reply Last reply
                                        0
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes


                                        • Login

                                        • Don't have an account? Register

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • World
                                        • Users
                                        • Groups