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

    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