Memory not GCing after form closes

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Tyrsius
    New Member
    • Sep 2010
    • 6

    #1

    Memory not GCing after form closes

    First time posting, hope I can provide enough information that this makes sense. Sorry if this gets verbose, but I am sure someone will ask me an unrelated question before helping me, so I figure I might as well explain it all now.

    I am a Jr. developer at a small company working in as sort of an apprentice to an older developer (coding for 30+ years). The program is for internal use by employees as a ticket tracking system running as a front end for a SQL database. I noticed recently that a small group of users will periodically (once a week) get memory exceptions, so I got a profiling tool to look into the problem. I am having trouble working with the wealth of information it is supplying, and unfortunately the problem is not yet a large enough concern to my lead developer for him to pull away from his current project. I am hoping to be able to handle this without forcing him to stop what he is doing.

    The Problem:
    A commonly used form (MDI child) to view/edit tickets does not collect ANY of the gen 2 memory it is consuming when it is closed within a reasonable amount of time. It eventually must collect, or this issue would be affecting everyone, but in the shorter tests I have done (10-15 minutes) it does not collect at all.

    The profiler shows that the largest remnant from the form is datarows, referenced by the MDI parent from through a System.Windows. Forms.PropertyS tore+ObjectEntr y[]. I've read that this is due to .net not collecting the last MDI child. However, even if I open 3 forms, then close them all, none of the memory from ANY of them releases. The memory use in gen 2 just continues to grow. Gen 0 and 1 collect.

    In the MDI parent a dataset that stores a number of tables used for relations is copied by this MDI child form so that we aren't making continuous calls to the SQL server for them. I think this may be what the reference that is keeping the form alive is. I am not sure though. If this is the case, how do I remove this reference when or after closing the form?

    If this is not the case, how can I find what is being referenced?

    I know that is a lot, I appreciate any help you guys can give.
  • hype261
    New Member
    • Apr 2010
    • 207

    #2
    Garbage Collection

    Just because the form closes doesn't mean that the objects for the form are going to be Garbage Collected. Garbage collection occures when ever the CLR feels it is necessary, but you can request to have a Garbage Collection run using.

    Code:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    I would put this in your code after the form is closed and see if it frees up memory. It definitely seems like you are holding on to memory somewhere though.
    Last edited by Curtis Rutland; Sep 28 '10, 05:15 PM. Reason: Fixing code tags.

    Comment

    • Tyrsius
      New Member
      • Sep 2010
      • 6

      #3
      I tried that, and it did not affect the memory pool.

      I know that that it is holding onto memory somewhere, a reference from the MDI parent remains even after the form has dispose() called on it.

      I need some help understanding how to locate the reference, and/or how to destroy it.

      Comment

      • Tyrsius
        New Member
        • Sep 2010
        • 6

        #4
        I really feel like, based on the memory profiler's information, that the cause is these datasets.

        The MDI parent gets a bunch of tables from a SQL server when the program starts, and puts them in a dataset. The MDI Child uses dataset.copy() to get them without accessing the SQL server.

        Does using copy() create a reference to the MDI parent form? If so, how do I break this reference?

        Comment

        • Tyrsius
          New Member
          • Sep 2010
          • 6

          #5
          Not sure if bumping works in this forum, may have to repost.

          Comment

          • GaryTexmo
            Recognized Expert Top Contributor
            • Jul 2009
            • 1501

            #6
            What does your parent form do with the datasets after it copies them to the child?

            Or do you think the child is hanging around as well, resulting in more memory allocated every time a child is opened, then never released? By that I mean, if you keep opening and closing child forms, memory usage ramps up?

            Comment

            • Michael OC
              New Member
              • Oct 2010
              • 4

              #7
              What you need to do on form close is call the Dispose method for the Dataset not the Form. Something like ds.Dispose(). That will release it at that time.

              Comment

              • Tyrsius
                New Member
                • Sep 2010
                • 6

                #8
                The parent form holds the datasets until the program closes, as the child is a commonly used form. However, the copy is done in the child form by accessing the public datasets in the parent.

                And yes, the memory usage keeps ramping up, I believe the child windows are hanging around. The memory profiler stats that dispose() has been called on the form and datasets/rows that are there, but that doesn't stop them from remaining live in Gen 2 memory for some reason.

                @Michael: I have tried that, it did not seem to have an effect.

                Thanks for the response guys =)

                Comment

                • Michael OC
                  New Member
                  • Oct 2010
                  • 4

                  #9
                  Have you tried ds.Dispose() on the Child and the Parent?

                  Comment

                  • hype261
                    New Member
                    • Apr 2010
                    • 207

                    #10
                    Have you tried instead of doing dataset.copy just passing a reference of the dataset to your child window? MSDN leads me to believe that .copy does a deep copy of the dataset and that could be held on to by something.

                    Comment

                    • Tyrsius
                      New Member
                      • Sep 2010
                      • 6

                      #11
                      If I call dispose() on the parent, then it might GC. The reason we do this copy is to maintain the Parent for the life of the application so that calling a select/fill from the database is not needed multiple times.

                      If a reference is passed, then the parent datasets will be changed by the parent. The reason for the copy is to allow the datasets to be worked with and databound to the child form.

                      If you are right about copy holding on to something, how can it be let go? I have been thinking that something like that has been the problem, but I don't know how to fix it.

                      Comment

                      • GaryTexmo
                        Recognized Expert Top Contributor
                        • Jul 2009
                        • 1501

                        #12
                        Is there a way you can boil this down to a simple test to experiment with? I usually like to isolate the problem in a separate solution... in this case I'd manually create a small dataset, then try copying it and loading it on another form. If I can reproduce it in this smaller scale, I can then attack the problem and experiment with solutions with comfortable in the knowledge that I have fewer external factors.

                        It also means I (and by I, I mean you) can post the code on a forum so people can help me debug ;)

                        I wonder if it would be worthwhile for you to write your own copy method in order to ensure you're making duplicates and not accidentally keeping any references around. I'd try this on the smaller scale project first, I'd imagine a manual dataset copy could be a big bit of code.

                        Comment

                        Working...