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
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. Memory allocation / GC issues???

Memory allocation / GC issues???

Scheduled Pinned Locked Moved .NET (Core and Framework)
csharphelpc++performance
18 Posts 7 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.
  • X Xpnctoc

    So in other words, I'm paranoid. The application I'm writing requires a potentially unlimited amount of user data. Well of course this is impossible because a computer only has a finite amount of memory. But what I've been worried about is that someday I'll be using the app and I'll hit memory capacity because the GC didn't reallocate 100MB+ that was used up in temporary dialog boxes in menus. But if it's just because the GC is lazy and doesn't kick in until absolutely necessary, then I guess I should be OK.

    L Offline
    L Offline
    Luc Pattyn
    wrote on last edited by
    #7

    Hi, there are good reasons why the gc is lazy, and should not be called explicitly: 1. it is an expensive operation, since it needs to check all the data in your app, figuring out which objects still have references to them (are "alive") and which don't. There can be a lot of data involved, it does not fit in the cache, and it trashes the cache (i.e. whatever was rightfully in there now is gone). 2. while doing its job, the gc suspends all your threads, to make sure the stacks and objects don't change while it is examining them; so your app is temporarily dead. :)

    Luc Pattyn [Forum Guidelines] [My Articles]


    this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


    1 Reply Last reply
    0
    • X Xpnctoc

      Hello, I posted the following in the C++/CLI forum, because the application I was writing when I noticed the problem is written in C++/CLI. However, the thought occured to me that maybe this is something .NET developers in C# or VB.NET have also experienced. Please take a read through and let me know what you think. Thanks! Yesterday I tried an experiment.... I took a C++/CLI application of mine and disabled my menu-disabling code so that my full menu system (with fly-outs) would work even when no application data was open. Using Task Manager to monitor my memory use, I noticed that every time I expanded a top-level menu or moused over a sub-menu that triggered a fly-out, more memory was used. No shock there. BUT, when I click back in the main window area to make all the fly-outs disappear, the memory use does NOT decrease! In fact, I sat there for 10 minutes waiting for Task Manager to show some drop in memory use, but it never did. Meanwhile, when I triggered the same fly-out again, even MORE memory was used. I noticed the same behavior when I triggered the Open File Dialog (.NET out of the box -- no overrides or anthing weird). The application I am writing is very dialog-intensive. The base application uses about 64MB. But at the consumption rates I'm seeing, I could very well imagine that after an hour or so I'd be up to 512MB from invoking dialogs and the GC failing to reclaim memory. What the heck is going on? Is my Garbage Collector broken? Should I somehow manually invoke garbage collection to clear some memory? Does anyone know if the GC works on a time interval or a certain percentage of consumed memory, or what? Thanks for your help.

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #8

      You may want to display (and periodically update) the value of Environment.WorkingSet inside your app; that allows you to see memory usage by your process.

      Luc Pattyn [Forum Guidelines] [My Articles]


      this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


      X 1 Reply Last reply
      0
      • X Xpnctoc

        Hello, I posted the following in the C++/CLI forum, because the application I was writing when I noticed the problem is written in C++/CLI. However, the thought occured to me that maybe this is something .NET developers in C# or VB.NET have also experienced. Please take a read through and let me know what you think. Thanks! Yesterday I tried an experiment.... I took a C++/CLI application of mine and disabled my menu-disabling code so that my full menu system (with fly-outs) would work even when no application data was open. Using Task Manager to monitor my memory use, I noticed that every time I expanded a top-level menu or moused over a sub-menu that triggered a fly-out, more memory was used. No shock there. BUT, when I click back in the main window area to make all the fly-outs disappear, the memory use does NOT decrease! In fact, I sat there for 10 minutes waiting for Task Manager to show some drop in memory use, but it never did. Meanwhile, when I triggered the same fly-out again, even MORE memory was used. I noticed the same behavior when I triggered the Open File Dialog (.NET out of the box -- no overrides or anthing weird). The application I am writing is very dialog-intensive. The base application uses about 64MB. But at the consumption rates I'm seeing, I could very well imagine that after an hour or so I'd be up to 512MB from invoking dialogs and the GC failing to reclaim memory. What the heck is going on? Is my Garbage Collector broken? Should I somehow manually invoke garbage collection to clear some memory? Does anyone know if the GC works on a time interval or a certain percentage of consumed memory, or what? Thanks for your help.

        realJSOPR Offline
        realJSOPR Offline
        realJSOP
        wrote on last edited by
        #9

        A side note - don't allocate more than about 85k of memory to any single object unless you're prepare to handle cleanup manually. Anything bigger than that gets shoved onto the "large object heap", and the GC doesn't clean that up for you.

        "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
        -----
        "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

        X L 2 Replies Last reply
        0
        • realJSOPR realJSOP

          A side note - don't allocate more than about 85k of memory to any single object unless you're prepare to handle cleanup manually. Anything bigger than that gets shoved onto the "large object heap", and the GC doesn't clean that up for you.

          "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
          -----
          "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

          X Offline
          X Offline
          Xpnctoc
          wrote on last edited by
          #10

          Got that covered. All of my core logic I'm writing in unmanaged code. I found early on that I didn't like the overhead of some of the System.Collections.Generic classes -- especially the bulky disk usage in serialization compared to doing a straight binary write of unmanaged data structures. So I chose to write the app in C++/CLI, using .NET for the ease of creating Windows forms and controls while keeping my core logic and processing in native C++. So I'm fully prepared to do my unmanaged allocation and cleanup. Like I said, the behavior I'm calling into question occurs with things I have little or no control over, such as Menu controls and dialogs.

          1 Reply Last reply
          0
          • L Luc Pattyn

            You may want to display (and periodically update) the value of Environment.WorkingSet inside your app; that allows you to see memory usage by your process.

            Luc Pattyn [Forum Guidelines] [My Articles]


            this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


            X Offline
            X Offline
            Xpnctoc
            wrote on last edited by
            #11

            Thanks for the tip. I wasn't aware of that one. I'm sure that will help.

            1 Reply Last reply
            0
            • realJSOPR realJSOP

              A side note - don't allocate more than about 85k of memory to any single object unless you're prepare to handle cleanup manually. Anything bigger than that gets shoved onto the "large object heap", and the GC doesn't clean that up for you.

              "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
              -----
              "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

              L Offline
              L Offline
              Luc Pattyn
              wrote on last edited by
              #12

              Hi John, I don't fully agree, AFAIK objects on the large object heap are managed like all other managed objects, with a single difference: the LOH does not get reshuffled, hence there is a risk of fragmentation. Example: allocate 1MB, then 100MB, repeat this N times until memory is almost full, then throw away the references to all 100MB objects and try to get one really big object of 300MB. IMO the threshold (85KB?) is not documented, is not available through some API, may vary over time, and may depend on your system's memory situation. I feel the Framework should be more specific about this, it should guarantee a reasonable minimum value for the threshold, so one can make sure fragmentation will not become an issue by keeping objects smaller than that. :)

              Luc Pattyn [Forum Guidelines] [My Articles]


              this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


              S 1 Reply Last reply
              0
              • D Dave Kreskowiak

                Well, that doesn't exactly guarantee you won't run out of memory. You can still cause leaks, like resources and handles. For example, with all these dialogs, are you showing them by calling .ShowDialog()?? If so, are you then calling .Dispose() on those dialogs when you're done with the data in them?? If not, you'll eventually run the system out of resources and cause an OutOfMemory exception.

                A guide to posting questions on CodeProject[^]
                Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                     2006, 2007

                L Offline
                L Offline
                Lutoslaw
                wrote on last edited by
                #13

                Hey, I though that a code

                openFileDialog.ShowDialog();
                openFileDialog.Dispose();
                openFileDialog.ShowDialog();

                throws "object disposed" excpt or sth like that, doesn't it? So if I use this dialog all the time...

                Greetings - Gajatko

                L D 2 Replies Last reply
                0
                • L Lutoslaw

                  Hey, I though that a code

                  openFileDialog.ShowDialog();
                  openFileDialog.Dispose();
                  openFileDialog.ShowDialog();

                  throws "object disposed" excpt or sth like that, doesn't it? So if I use this dialog all the time...

                  Greetings - Gajatko

                  L Offline
                  L Offline
                  Luc Pattyn
                  wrote on last edited by
                  #14

                  of course you only dispose of things you don't need any longer.

                  Luc Pattyn [Forum Guidelines] [My Articles]


                  this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


                  1 Reply Last reply
                  0
                  • L Luc Pattyn

                    Hi John, I don't fully agree, AFAIK objects on the large object heap are managed like all other managed objects, with a single difference: the LOH does not get reshuffled, hence there is a risk of fragmentation. Example: allocate 1MB, then 100MB, repeat this N times until memory is almost full, then throw away the references to all 100MB objects and try to get one really big object of 300MB. IMO the threshold (85KB?) is not documented, is not available through some API, may vary over time, and may depend on your system's memory situation. I feel the Framework should be more specific about this, it should guarantee a reasonable minimum value for the threshold, so one can make sure fragmentation will not become an issue by keeping objects smaller than that. :)

                    Luc Pattyn [Forum Guidelines] [My Articles]


                    this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


                    S Offline
                    S Offline
                    Scott Dorman
                    wrote on last edited by
                    #15

                    Luc Pattyn wrote:

                    the threshold (85KB?) is not documented, is not available through some API, may vary over time, and may depend on your system's memory situation.

                    In general this is true, the 85KB limit isn't publicly documented. I did find it in Rotor[^] (SSCLI) in the gc.h header file for the garbage collector's native code:

                    /* misc defines */
                    #define LARGE_OBJECT_SIZE 85000

                    .

                    Scott.


                    —In just two days, tomorrow will be yesterday. [Forum Guidelines] [Articles] [Blog]

                    1 Reply Last reply
                    0
                    • L Lutoslaw

                      Hey, I though that a code

                      openFileDialog.ShowDialog();
                      openFileDialog.Dispose();
                      openFileDialog.ShowDialog();

                      throws "object disposed" excpt or sth like that, doesn't it? So if I use this dialog all the time...

                      Greetings - Gajatko

                      D Offline
                      D Offline
                      Dave Kreskowiak
                      wrote on last edited by
                      #16

                      gajatko wrote:

                      So if I use this dialog all the time...

                      You create a new instance of it...

                      A guide to posting questions on CodeProject[^]
                      Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                           2006, 2007

                      1 Reply Last reply
                      0
                      • X Xpnctoc

                        Hello, I posted the following in the C++/CLI forum, because the application I was writing when I noticed the problem is written in C++/CLI. However, the thought occured to me that maybe this is something .NET developers in C# or VB.NET have also experienced. Please take a read through and let me know what you think. Thanks! Yesterday I tried an experiment.... I took a C++/CLI application of mine and disabled my menu-disabling code so that my full menu system (with fly-outs) would work even when no application data was open. Using Task Manager to monitor my memory use, I noticed that every time I expanded a top-level menu or moused over a sub-menu that triggered a fly-out, more memory was used. No shock there. BUT, when I click back in the main window area to make all the fly-outs disappear, the memory use does NOT decrease! In fact, I sat there for 10 minutes waiting for Task Manager to show some drop in memory use, but it never did. Meanwhile, when I triggered the same fly-out again, even MORE memory was used. I noticed the same behavior when I triggered the Open File Dialog (.NET out of the box -- no overrides or anthing weird). The application I am writing is very dialog-intensive. The base application uses about 64MB. But at the consumption rates I'm seeing, I could very well imagine that after an hour or so I'd be up to 512MB from invoking dialogs and the GC failing to reclaim memory. What the heck is going on? Is my Garbage Collector broken? Should I somehow manually invoke garbage collection to clear some memory? Does anyone know if the GC works on a time interval or a certain percentage of consumed memory, or what? Thanks for your help.

                        V Offline
                        V Offline
                        Vaibhav Sharma
                        wrote on last edited by
                        #17

                        Hi, I am amazed that after reading all the replies and posts on this article no one mentions of the Using...End Using code block. I am sure you must be knowing it but just a little bit of detailing on the using statements: 'VB Version, C# no different, just lang. changes Using dlgOpen As New OpenFileDialog() dlgOpen.Filter="*.*" 'Any other properties dlg.ShowDialog() End Using Now what the above code fragment does is that the CLR will create the dlgOpen object and will be responsible for its disposal, not YOU. This has serious benefits in terms of Performance & Memory Utilization since as soon as the code execution reaches End Using the dlgOpen will be Disposed off without requiring you to do any thing at all. :::One Catch Though While using the Using statements::: the dlgOpen will not be accessible outside the Using block since its scope is limited is to the Using...End Using block. So i strongly recommend you to go ahead and use the Using...End Using blocks for all the DialogBoxes since most of them times they return only one value which can easily be stored on a local/global variable. Awaiting reply eagerly.

                        Regards, Vaibhav Sharma

                        X 1 Reply Last reply
                        0
                        • V Vaibhav Sharma

                          Hi, I am amazed that after reading all the replies and posts on this article no one mentions of the Using...End Using code block. I am sure you must be knowing it but just a little bit of detailing on the using statements: 'VB Version, C# no different, just lang. changes Using dlgOpen As New OpenFileDialog() dlgOpen.Filter="*.*" 'Any other properties dlg.ShowDialog() End Using Now what the above code fragment does is that the CLR will create the dlgOpen object and will be responsible for its disposal, not YOU. This has serious benefits in terms of Performance & Memory Utilization since as soon as the code execution reaches End Using the dlgOpen will be Disposed off without requiring you to do any thing at all. :::One Catch Though While using the Using statements::: the dlgOpen will not be accessible outside the Using block since its scope is limited is to the Using...End Using block. So i strongly recommend you to go ahead and use the Using...End Using blocks for all the DialogBoxes since most of them times they return only one value which can easily be stored on a local/global variable. Awaiting reply eagerly.

                          Regards, Vaibhav Sharma

                          X Offline
                          X Offline
                          Xpnctoc
                          wrote on last edited by
                          #18

                          I appreciate the tip. I am aware of the "using" syntax, but in my case that won't work. As I mentioned in my response to John Simmons's post above, my application is written in C++/CLI, which has no such construct. There were multiple reasons for that language choice, some of which I mentioned and others that are irrelevant to this conversation. And even if I was in C#/VB, I'd still have the same problem with the Menu control. Can't use "using" for something like a menu that has to be present for the duration of execution. Regardless, I think it was one of Luc Pattyn's responses that directed me to try examining memory usage through the Environment.WorkingSet (thank's again, Luc). This provides memory use much closer to what I would expect based on my interaction with the application. I still find it alarming that the .NET virtual machine continues to eat up additional memory when it's not needed, but there I just have to trust that the GC will do its job when push comes to shove.

                          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