My intention is the share dll's between my applications, such that if for example I have 2 applications that load a 20MB dll, than instead of one process using 200MB memory and another with 200MB too, one of them will benefit from sharing and use only 180MB memory.
My problem is with the definition of memory, please keep reading.
I've created 2 .net c# applications that reference and run code frm a large dll (20MB) which is located in the GAC.
With .NET Memory Profiler I could see that indeed the actual physical memory that was used by the second process was significantly lower than the one that was started first (although they are identical) and that the dll was located under the shared memory of the first process.
Yet, when checking memory counters with perfmon I saw that the virtual memory of both applications increases (in correlation with the size of the dll) by the same size they increase when running each one alone.
This leads to the question: What point there is in sharing (memory-economic wise) dll's if only physical memory benefits from it but the virtual memory, which is from the application point of view, the thing that matters.
Edit: Thanks for the answers. Based on the answers, I want to emphasize that I understand the benefit of sharing dll's in memory to save physical ram. The more precise question I should be asking is:
Is there any benefit, application wise (not system wise), from the way dll's are shared between applications in .net?
The reason I'm asking this is because I do care about the amount of virtual memory that my applications are using (in total).
RAM matters. Virtual memory doesn't cost anything, it is virtual. Multiple processes sharing the same RAM is a Big Deal. Any Windows process has a dependency on kernel32.dll. But there's only one copy of its code in RAM.
Taking advantage of processes sharing code in a managed program requires running ngen.exe so that they all get the exact same machine code. Nothing can be shared if the code is just-in-time compiled.
What point there is in sharing (memory-economic wise) dll's if only physical memory benefits from it but the virtual memory, which is from the application point of view, the thing that matters.
I'm not sure how you're coming to that conclusion. A system has a limited amount of physical memory, not virtual memory, so saving physical memory is what effectively matters in the long run.
You don't seem to be thinking about this correctly. An application's process space is it's virtual memory. In order for the code to run, it must be mapped into the applications process space. Otherwise, how would it execute code that it could not actually see?
The physical memory is shared, but the CPU has to be able to see the virtual memory to execute it.
Think of it like this. Suppose you and your neighbors share a swimming pool. For all intents and purposes, each of you think the pool is included in your property. Only one physical pool exists, but each of you see it as part of your "virtual memory".
@duskwuff - well the system does have a limited amount of virtual memory too, albeit the limit is theoretically very large (but practically limited by the size of your page file). Apart from that, the observations made by the previous answers are correct up to a point.
In Windows, DLLs have a "preferred load address" built into their image. If this clashes with the load address of any other DLLs in the same process, then the loader has to "rebase" the DLL, which basically means going through and fixing up absolute references within the DLL. At this point, what's been loaded is no longer the same as what came from disk and (crucially) not the same as what has been loaded into the any other processes address space - which means it can't be shared between the processes.
Additionally, since it's not the same as what's on disk, if it needs to be swapped out, it will need to be written to the page file (which is where the bits of virtual memory that don't live in physical memory are stored).
So, although I don't think this is what is causing the issue that you're seeing in perfmon, it is worth bearing in mind when building your DLLs. You'll see debug output in the VS console if the DLL is getting rebased at load time.
You can set the preferred load address at build time, or use an SDK tool called rebase post-build. So, if you're building several DLLs make sure that their preferred load addresses don't clash. Even if you're only building one DLL you should check it doesn't clash with any others that your app depends on.
My understanding is that sharing through the GAC is intended to save space on the hard drive, not memory space. Each app that calls the DLL from the GAC will get its own in-memory copy of the DLL, as ghimireniraj said.