Memory Usage Inside the CLR
mattwarren.org
mattwarren.org
A "simple HelloWorld program" somehow is using 76 MEGAbytes of ram? How is that sane?
8.2KB is shared, 1.4KB is private.
According to the article most of that memory is because it's a DEBUG build and the debug CLR images are large.
I think the issue is that the tool is showing you what is mapped into the address space of the process which may not use any memory. It could be mapped files or copy on write pages etc.
I think that I'll update the post with RELEASE mode screenshots, because having DEBUG ones just confuses things. Very few people (no-one?) will be running a DEBUG version of the CLR in real-world situations, so it's a bit confusing to use it.
That being said, the huge "Image" section doesn't have to be as big as you're seeing. If you look at the breakdown [0], then you can see some debugging, in the form of "TraceDLL". He also mentions that the four biggest memory eaters: System.Private.CoreLib.dll, coreclr.dll, clrjit.dll and CoreRun.exe are probably bigger than normal, because he's using a debug version of the CLR.
Outside those five, every other piece of memory is shared, which changes how you see its allocation.
I'd expect it'd change a measurable amount, but as before... The CLR is best when handling bigger programs, where JITing can actually make sense.
[0] http://mattwarren.org/images/2017/07/Image%20Memory%20Usage....
Yeah that's a good point, I deliberately chose to do a 'Hello World' app to make it easier to see what the CLR itself was doing, so that there was the bare minimum of non-essential things going on (that would make it harder to see).
But the side-effect is that it does show the CLR in a bad-light, people expect 'Hello World' apps to be a bit 'slimmer'
* The debug DLLs of coreclr.dll and clrjit.dll are 4x bigger than the release DLLs. * The debug versions allocate more at runtime. * However in the blog post uses CoreRun.exe, which is a minimal testing harness. Dotnet.exe loads more DLLs.
On my computer I'm seeing something like 98MB commited, 8MB private, and 14MB working set. The committed number is not useful, as it a lot of DLLs get loaded in that only have a few functions in them called. The most charitable metric would be private work setting, which is 4MB.
Yeah, that's a good point. I'm going to update the post with RELEASE mode values, so that it's a better representation of a real app.
> On my computer I'm seeing something like 98MB commited, 8MB private, and 14MB working set. The committed number is not useful, as it a lot of DLLs get loaded in that only have a few functions in them called. The most charitable metric would be private work setting, which is 4MB.
The more I dug into this, the more I came to the conclusion that there is no one number that reflects the memory usage of an application, as you say, you almost always need to look at several values.
It's a good job VMMap exists as it makes it really easy to see the different values, I especially like that it detects the GC Heap as a separate category.
The linked libraries happen to be larger than usual because they are the debugging variants.
This type of question was exactly why I wrote the post, I've looked at the memory usage of a few .NET apps in the past and thought exactly the same thing :-)
I hope that if people get nothing else from my post, they'll at least take a look at VMMap and see some more context for that overall value.
76MB may seem like a relatively tiny amount now (it's <1% of a typical PC's RAM today), but in absolute terms that is still seventy-six million bytes. One should naturally wonder why that much memory is required to display a simple string of text.
Its not but by and large when people open a .NET project they want to do more than just print text, hence the inclusion of many .NET assemblies that enable the programmer to perform a variety of tasks.
If your only task is to print text then yes, its the wrong tool for the job.