Simple problem: Why does this cause a massive memory leak?

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

    Simple problem: Why does this cause a massive memory leak?

    Hi all,

    I have a huge memory leak problem in what is really very simple data
    insert code.

    In my app I'm trying to use a typed dataset to insert into a database.
    It adds quite a few rows (say hundreds). Unfortunately it has a big ass
    memory leak and I dont understand why.

    The code below demonstrates the memory leak. It's like nothing is
    cleaned up after PerformOperatio n is called.

    According to .net memory profiler, after running the console app, there
    are huge numbers of undisposed objects and meory usage is through the roof.

    I've tried to attach a screenshot from .net memory profiler showing what
    I mean

    Any help would be very much appreciated

    Thanks

    Simon

    class Program {

    static void Main(string[] args) {
    for (int i = 0; i < 1000; i++) {
    PerformOperatio n();
    }
    }

    private static void PerformOperatio n() {
    GPSPositionTabl eAdapter da = new GPSPositionTabl eAdapter();
    GPSPositionTabl e tblGPSPositions = new GPSPositionTabl e();
    GPSPositionRow currentRow = null;

    for (int i = 0; i < 50; i++) {

    currentRow = tblGPSPositions .NewGPSPosition Row();

    currentRow.Down loadID = 1;
    currentRow.TTUR eference = 9999;
    currentRow.Time stamp = DateTime.Now;
    currentRow.Lati tude = 66.66666666666;
    currentRow.Long itude = 66.66666666666;

    tblGPSPositions .AddGPSPosition Row(currentRow) ;
    }

    da.Update(tblGP SPositions);
    }

    }
  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: Simple problem: Why does this cause a massive memory leak?

    Simon,

    I am curious, why do you think there should be disposed objects? The GC
    is not deterministic, and you cant say by looking at a program "I should
    have disposed objects here". The only place you can even begin to make that
    sort of assumption is where you have an explicit call to the static Collect
    method on the GC class, which you do not have here.

    What is it that you are looking to do?


    --
    - Nicholas Paldino [.NET/C# MVP]
    - mvp@spam.guard. caspershouse.co m

    "Simon" <simon@nothanks .comwrote in message
    news:uqw3NTOaHH A.3996@TK2MSFTN GP03.phx.gbl...
    Hi all,
    >
    I have a huge memory leak problem in what is really very simple data
    insert code.
    >
    In my app I'm trying to use a typed dataset to insert into a database. It
    adds quite a few rows (say hundreds). Unfortunately it has a big ass
    memory leak and I dont understand why.
    >
    The code below demonstrates the memory leak. It's like nothing is cleaned
    up after PerformOperatio n is called.
    >
    According to .net memory profiler, after running the console app, there
    are huge numbers of undisposed objects and meory usage is through the
    roof.
    >
    I've tried to attach a screenshot from .net memory profiler showing what I
    mean
    >
    Any help would be very much appreciated
    >
    Thanks
    >
    Simon
    >
    class Program {
    >
    static void Main(string[] args) {
    for (int i = 0; i < 1000; i++) {
    PerformOperatio n();
    }
    }
    >
    private static void PerformOperatio n() {
    GPSPositionTabl eAdapter da = new GPSPositionTabl eAdapter();
    GPSPositionTabl e tblGPSPositions = new GPSPositionTabl e();
    GPSPositionRow currentRow = null;
    >
    for (int i = 0; i < 50; i++) {
    >
    currentRow = tblGPSPositions .NewGPSPosition Row();
    >
    currentRow.Down loadID = 1;
    currentRow.TTUR eference = 9999;
    currentRow.Time stamp = DateTime.Now;
    currentRow.Lati tude = 66.66666666666;
    currentRow.Long itude = 66.66666666666;
    >
    tblGPSPositions .AddGPSPosition Row(currentRow) ;
    }
    >
    da.Update(tblGP SPositions);
    }
    >
    }

    Comment

    • Ben Voigt

      #3
      Re: Simple problem: Why does this cause a massive memory leak?

      According to .net memory profiler, after running the console app, there
      are huge numbers of undisposed objects and meory usage is through the
      roof.
      If you want objects to be disposed, as opposed to finalized during
      collection, you must call IDisposable.Dis pose on each object. The using
      clause is a convenient way to do this in most cases.


      Comment

      • Cor Ligthert [MVP]

        #4
        Re: Simple problem: Why does this cause a massive memory leak?

        simon,

        See inline
        private static void PerformOperatio n() {
        GPSPositionTabl eAdapter da = new GPSPositionTabl eAdapter();
        GPSPositionTabl e tblGPSPositions = new GPSPositionTabl e();
        This is te place where the old tblGSSPostition s should be given to the GC as
        long as there are no rows anymore to it attached by instance by the
        currentRow which is added to the tblGPSPpostitio ns.

        Maybe will a simple clear before the new help in this.

        Cor

        GPSPositionRow currentRow = null;
        >
        for (int i = 0; i < 50; i++) {
        >
        currentRow = tblGPSPositions .NewGPSPosition Row();
        >
        currentRow.Down loadID = 1;
        currentRow.TTUR eference = 9999;
        currentRow.Time stamp = DateTime.Now;
        currentRow.Lati tude = 66.66666666666;
        currentRow.Long itude = 66.66666666666;
        >
        tblGPSPositions .AddGPSPosition Row(currentRow) ;
        }
        >
        da.Update(tblGP SPositions);
        }
        >
        }

        Comment

        • Simon

          #5
          Re: Simple problem: Why does this cause a massive memory leak?

          Hi Guys,

          Thanks for your thoughts on this.

          The reason why its troubling me is that this application runs non-stop.
          Over a period of say, 24hrs, the memory usage of the application
          balloons to over 400 meg. If I leave it long enough, it will eventually
          throw an exception due to running out of memory. Even if it wasn't
          throwing a memory exception - why hasn't the garbage collector kicked in
          much sooner?

          Either way, I need to get it to stop using so much memory, and all the
          undisposed instances in memory profiler seemed to be the culprit.

          Is this behaviour normal? Can you tell me what to do?

          Sincerest Thanks

          Simon

          Comment

          • Simon

            #6
            Re: Simple problem: Why does this cause a massive memory leak?

            Cor Ligthert [MVP] wrote:
            simon,
            >
            See inline
            >private static void PerformOperatio n() {
            > GPSPositionTabl eAdapter da = new GPSPositionTabl eAdapter();
            > GPSPositionTabl e tblGPSPositions = new GPSPositionTabl e();
            >
            This is te place where the old tblGSSPostition s should be given to the GC as
            long as there are no rows anymore to it attached by instance by the
            currentRow which is added to the tblGPSPpostitio ns.
            >
            Maybe will a simple clear before the new help in this.
            >
            Cor
            >
            >
            > GPSPositionRow currentRow = null;
            >>
            > for (int i = 0; i < 50; i++) {
            >>
            >currentRow = tblGPSPositions .NewGPSPosition Row();
            >>
            >currentRow.Dow nloadID = 1;
            >currentRow.TTU Reference = 9999;
            >currentRow.Tim estamp = DateTime.Now;
            >currentRow.Lat itude = 66.66666666666;
            >currentRow.Lon gitude = 66.66666666666;
            >>
            >tblGPSPosition s.AddGPSPositio nRow(currentRow );
            > }
            >>
            > da.Update(tblGP SPositions);
            >}
            >>
            >}
            >
            >

            Hi Cor,

            As I understand it, tblGPSPositions should be made available to the
            garbage collector as soon as PerformOperatio n goes out of scope, not when

            GPSPositionTabl e tblGPSPositions = new GPSPositionTabl e();

            is called. Is this not the case?

            Thanks

            Simon

            Comment

            • Cor Ligthert [MVP]

              #7
              Re: Simple problem: Why does this cause a massive memory leak?

              Simon,

              Did you do what I wrote?

              Cor

              "Simon" <simon@nothanks .comschreef in bericht
              news:Ov1diGVaHH A.3996@TK2MSFTN GP03.phx.gbl...
              Hi Guys,
              >
              Thanks for your thoughts on this.
              >
              The reason why its troubling me is that this application runs non-stop.
              Over a period of say, 24hrs, the memory usage of the application balloons
              to over 400 meg. If I leave it long enough, it will eventually throw an
              exception due to running out of memory. Even if it wasn't throwing a
              memory exception - why hasn't the garbage collector kicked in much sooner?
              >
              Either way, I need to get it to stop using so much memory, and all the
              undisposed instances in memory profiler seemed to be the culprit.
              >
              Is this behaviour normal? Can you tell me what to do?
              >
              Sincerest Thanks
              >
              Simon

              Comment

              • Simon

                #8
                Re: Simple problem: Why does this cause a massive memory leak?

                Hi Cor,

                Thanks for your reply. I havent had a chance to try what you're
                suggesting as the code is on another machine, but I can't see why it
                would work...

                PerformOperatio n is called say, 100 times and each time the datatable
                and data adapter et al should go completely out of scope and therefore
                be fair game for the GC.

                If I call Clear on the data table just after it's create as you suggest,
                I'd be calling clear on a completely new instance with nothing in it...

                Am I perhaps misunderstandin g something?

                Many thanks

                Simon

                Comment

                • Miha Markic [MVP C#]

                  #9
                  Re: Simple problem: Why does this cause a massive memory leak?

                  You should look for live (not disposed) instances - those are causing
                  problems.
                  Anyway, what live instances are there?

                  --
                  Miha Markic [MVP C#, INETA Country Leader for Slovenia]
                  RightHand .NET consulting & development www.rthand.com
                  Blog: http://cs.rthand.com/blogs/blog_with_righthand/


                  "Simon" <simon@nothanks .comwrote in message
                  news:uqw3NTOaHH A.3996@TK2MSFTN GP03.phx.gbl...
                  Hi all,
                  >
                  I have a huge memory leak problem in what is really very simple data
                  insert code.
                  >
                  In my app I'm trying to use a typed dataset to insert into a database. It
                  adds quite a few rows (say hundreds). Unfortunately it has a big ass
                  memory leak and I dont understand why.
                  >
                  The code below demonstrates the memory leak. It's like nothing is cleaned
                  up after PerformOperatio n is called.
                  >
                  According to .net memory profiler, after running the console app, there
                  are huge numbers of undisposed objects and meory usage is through the
                  roof.
                  >
                  I've tried to attach a screenshot from .net memory profiler showing what I
                  mean

                  Comment

                  • VJ

                    #10
                    Re: Simple problem: Why does this cause a massive memory leak?

                    Smion, how do you say there is a memory leak?.. Did you see the windows task
                    manager or use a memory profiler tool ???

                    VJ

                    "Simon" <simon@nothanks .comwrote in message
                    news:uqw3NTOaHH A.3996@TK2MSFTN GP03.phx.gbl...
                    Hi all,
                    >
                    I have a huge memory leak problem in what is really very simple data
                    insert code.
                    >
                    In my app I'm trying to use a typed dataset to insert into a database. It
                    adds quite a few rows (say hundreds). Unfortunately it has a big ass
                    memory leak and I dont understand why.
                    >
                    The code below demonstrates the memory leak. It's like nothing is cleaned
                    up after PerformOperatio n is called.
                    >
                    According to .net memory profiler, after running the console app, there
                    are huge numbers of undisposed objects and meory usage is through the
                    roof.
                    >
                    I've tried to attach a screenshot from .net memory profiler showing what I
                    mean
                    >
                    Any help would be very much appreciated
                    >
                    Thanks
                    >
                    Simon
                    >
                    class Program {
                    >
                    static void Main(string[] args) {
                    for (int i = 0; i < 1000; i++) {
                    PerformOperatio n();
                    }
                    }
                    >
                    private static void PerformOperatio n() {
                    GPSPositionTabl eAdapter da = new GPSPositionTabl eAdapter();
                    GPSPositionTabl e tblGPSPositions = new GPSPositionTabl e();
                    GPSPositionRow currentRow = null;
                    >
                    for (int i = 0; i < 50; i++) {
                    >
                    currentRow = tblGPSPositions .NewGPSPosition Row();
                    >
                    currentRow.Down loadID = 1;
                    currentRow.TTUR eference = 9999;
                    currentRow.Time stamp = DateTime.Now;
                    currentRow.Lati tude = 66.66666666666;
                    currentRow.Long itude = 66.66666666666;
                    >
                    tblGPSPositions .AddGPSPosition Row(currentRow) ;
                    }
                    >
                    da.Update(tblGP SPositions);
                    }
                    >
                    }

                    Comment

                    • Simon

                      #11
                      Re: Simple problem: Why does this cause a massive memory leak?

                      Hi Everyone,

                      I have a small confession to make - I was misunderstandin g the readings
                      I was getting from the memory profiler. There is a memory leak, but it
                      isn't in the code that I posted. That code on its own doesnt cause a
                      memory leak.

                      I do still have a problem though that I don't know how to fix. It the
                      code I posted earlier, I ommitted (for clarity) the fact that I actually
                      download stuff using a COM component before adding it to the database.

                      It is this unmanaged code that is the source of the memory leak. Can
                      anyone give me any general advice on how to ensure that these COM
                      objects are cleaned up as I loop through each COM object?

                      Sorry for the confusion. You've all been very helpful though so thank
                      you everyone. You convinced me that the managed code shouldnt be the
                      source of the problem and made me look again at the unmanaged issue - an
                      area that I thought I had eliminated from my enquiries.

                      Sorry and thanks again

                      Simon

                      Comment

                      • VJ

                        #12
                        Re: Simple problem: Why does this cause a massive memory leak?

                        Implement IDisposable on COM objects and explicitly release unmaged
                        resources in this. And when using the com object instance, always call
                        dispose() when done.The link or example with MSDN IDisposible documentation
                        should help you get started. if you have questions ask.

                        VJ

                        "Simon" <simon@nothanks .comwrote in message
                        news:OvHWWlXaHH A.3584@TK2MSFTN GP02.phx.gbl...
                        Hi Everyone,
                        >
                        I have a small confession to make - I was misunderstandin g the readings I
                        was getting from the memory profiler. There is a memory leak, but it isn't
                        in the code that I posted. That code on its own doesnt cause a memory
                        leak.
                        >
                        I do still have a problem though that I don't know how to fix. It the code
                        I posted earlier, I ommitted (for clarity) the fact that I actually
                        download stuff using a COM component before adding it to the database.
                        >
                        It is this unmanaged code that is the source of the memory leak. Can
                        anyone give me any general advice on how to ensure that these COM objects
                        are cleaned up as I loop through each COM object?
                        >
                        Sorry for the confusion. You've all been very helpful though so thank you
                        everyone. You convinced me that the managed code shouldnt be the source of
                        the problem and made me look again at the unmanaged issue - an area that I
                        thought I had eliminated from my enquiries.
                        >
                        Sorry and thanks again
                        >
                        Simon

                        Comment

                        • Simon

                          #13
                          Re: Simple problem: Why does this cause a massive memory leak?

                          Hi VJ

                          Thanks for your reply.

                          I'm not sure how to "implement IDisposable" on these objects as they
                          don't have any such method. The COM objects are part of a third party
                          programming API that I have no control over.

                          How do I get rid of them if they dont have a Dispose() method or any
                          obvious equivelant?

                          Thanks again

                          Simon

                          Comment

                          • David Browne

                            #14
                            Re: Simple problem: Why does this cause a massive memory leak?



                            "Simon" <simon@nothanks .comwrote in message
                            news:OcNlsUYaHH A.2076@TK2MSFTN GP04.phx.gbl...
                            Hi VJ
                            >
                            Thanks for your reply.
                            >
                            I'm not sure how to "implement IDisposable" on these objects as they don't
                            have any such method. The COM objects are part of a third party
                            programming API that I have no control over.
                            >
                            How do I get rid of them if they dont have a Dispose() method or any
                            obvious equivelant?
                            >
                            Yeah, that's nonsense. If the COM component really has a memory leak, you
                            would need to fix it in the COM component.

                            However, often .NET code using COM components have poor memory performance
                            because the Runtime Callable Wrappers that .NET uses to wrap the COM
                            interface pointers will not destroy the COM component until they are
                            finalized. This can cause lots of memory problems, although it's not
                            technically a leak. As a best practice, anytime you are using a COM
                            component from .NET, explicitly call
                            System.Runtime. InteropServices .Marshal.Releas eComObject when you are done
                            with the COM component. This will immediately decrement the reference count
                            on the COM component and should clean up any unmanaged memory associated
                            with the component.

                            David


                            Comment

                            • Simon

                              #15
                              Re: Simple problem: Why does this cause a massive memory leak?

                              Hi Guys,

                              Thanks for your help so far.

                              I have a couple of questions I'm hoping someone could help me with.

                              1. If I have a method that creates and uses some COM objects, will the
                              resources that those COM objects were using be fair game for release as
                              soon as they go out of scope? Or do I have to do something to get rid of
                              them?

                              2. Dave mentioned calling
                              System.Runtime. InteropServices .Marshal.Releas eComObject. I had found a
                              reference to this when googling, but discounted it because the official
                              documentation said that it should only be used for testing purposes.
                              Something about the behaviour being undefined under certain operating
                              conditions. Should I use this?

                              Surely there must be a well known way of getting rid of COM gubbins once
                              I'm done with it. It sure isn't happening automatically though....

                              Thanks all

                              Simon

                              Comment

                              Working...