4

I seek advice on either proving or dispelling a belief that is held in my team (apparently without reason). The believe is that starting a new .Net application process is expensive memory-wise (20MB and up per-process). While I point out that the app clearly isn't using that much (as seen in the memory profiler), they counter-argue that it is not the app, but the .Net Framework's runtime that consumes the memory.

This is based on something they've all heard somewhere, so no solid proof exist, but the belief is extremely ingrained in the team. I've googled around, but I can't find any serious analysis of per-process cost of .Net Framework's runtime. While I simply can't accept that each .Net process is that expensive (though I'm willing to admit I may be wrong on this), I do not know enough to prove my point. My teammates on the other hand don't know enough to prove me wrong. Does anyone know of any research/analysis on the matter?

Thank you.

Alex K
  • 10,835
  • 8
  • 29
  • 34
  • this is probably somewhat true, see related SO threads http://stackoverflow.com/questions/1343374/reducing-memory-usage-of-net-applications http://stackoverflow.com/questions/223283/net-exe-memory-footprint – BrokenGlass Feb 06 '11 at 15:57
  • Those are not really related questions. They are concerned with reducing the cost of an application itself doing its work. What I am concerned with is the cost of CLR per-process (regardless of what the app does or how it does it). – Alex K Feb 06 '11 at 16:15

2 Answers2

5

Well, it is all relative. A process in Windows is in general an expensive resource, but only if you compare it to an operating system like Unix. The normal Windows resource sharing rules are in effect for a managed process. There will only ever be one copy in physical memory for the code in the CLR, JIT compiler and any assembly that is ngen-ed which includes all of the .NET framework assemblies. The Windows memory manager simply maps the same pages in all processes that uses these DLLs.

What is not shared is the Private Bytes, you can see this number with a tool like SysInternal's Process Explorer. The bigger chunks of private bytes in a .NET process are

  • the garbage collected heap
  • stacks used by threads, by default 1 MB a piece
  • any static variables used by the code loaded in an AppDomain
  • just-in-time generated code for assemblies that weren't ngen-ed
  • the private data for the CLR and the jitter.

Clearly using ngen.exe can significantly cut down on the amount of private bytes, as long as you use the assembly in more than one process. An AppDomain is .NET's way to cut down on the cost of a process and still achieve a level of isolation, used to great effect in custom CLR hosts like ASP.NET and SQL Server. If you have the option to run code in a thread vs running it in another process then a thread should always be the preferred choice.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • All of those things make sense, but most of them are costs of an application doing its work (the first 3 of your bullet points) not the cost of CLR. What I'm trying to find analysis on is the difference between running the same code as a stand alone app or as a linked DLL in another app. Is that really 20MB and higher? That's the core of my question. I really wish there was some statistical/experimental analysis report on this. I'll even take an MS sponsored one :) – Alex K Feb 06 '11 at 16:07
  • I don't understand why you'd think the two cases are different. They both involve a process, they both require the same runtime support, they both require loading the same chunk of code. Whether that code is stored in an EXE or a DLL makes no difference, the IL and metadata is exactly the same. – Hans Passant Feb 06 '11 at 16:15
  • So you are saying there is zero difference in memory consumption between the 2 cases? To re-iterate, my teammates believe that there would be at least 20MB difference. – Alex K Feb 06 '11 at 16:17
  • The only way they could make sense is when they compare a DLL with only native code vs a managed DLL. Yeah, 20 megabytes could be about right. It is otherwise comparing apples and oranges. Why don't you just ask them what that 20 megabytes is getting used for? – Hans Passant Feb 06 '11 at 16:24
3

I just started 100 .NET console apps on my laptop with just Console.ReadKey() in them. That increased my physical memory usage from 2.0 GB to 2.4 GB (I have 6 GB total, so no memory stress occured).

That amounts to 4 MB per process - quite affordable I would say.

Anyway, measuring memory consumption under windows and .NET actually is rocket science, as there are lots of different memory types that under certain circumstances can be shared or not.

TToni
  • 9,145
  • 1
  • 28
  • 42
  • Thanks for the experiment :) As for the _rocket science_ comment: that's why I was secretly hoping someone would be able to point me to an MS blog/article/paper on the subject that would provide the view on the subject by the people who know more than us mortals about the .Net internals. – Alex K Feb 06 '11 at 17:03