Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / July 2007

Tip: Looking for answers? Try searching our database.

No improvement in memory usage after using GAC and nGEN

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Nick John - 28 Jun 2007 07:21 GMT
Hi,

I've installed a number of assemblies into the GAC (using gacutil) and then
used nGen on them (nGen install) but can see no change in the memory usage
of applications that use them.

I'm running at least 3 instances of the application on the same machine as
the same user and using Process Explorer to display the Working Set and
Virtual Size of the applications.

I understood (see
http://msdn.microsoft.com/msdnmag/issues/06/05/clrinsideout/default.aspx)
that memory usage should be reduced as the applications should be sharing
the single nGen image of an assembly rather than each one having their JIT
image of the assembly.

Am I missing something?

The assemblies I'm testing with are not large.  Combined they are about 600K
in size (size of the DLL files). Is there some overhead in using nGen which
increases memory usage by about the same amount as I'm saving in this case
or something?

Cheers,
Nick
Günter Prossliner - 28 Jun 2007 12:41 GMT
Hello Nick!

> I've installed a number of assemblies into the GAC (using gacutil)
> and then used nGen on them (nGen install) but can see no change in
[quoted text clipped - 3 lines]
> machine as the same user and using Process Explorer to display the
> Working Set and Virtual Size of the applications.

When a dll is loaded into the (virtual) Address-Space of a process, and than
into another process, from the process the virtual memory starting at the
Base-Address (HINSTANCE) looks like any other (private) Memory. When the
process would write into this (shared) Memory (maybe because of relocation),
the Memory Manager by itself would create copies of the modified pages that
can no longer be shared (copy on write).

AFAIK the "WorkingSet" and "VM Size" Counters of the Task-Manager are not
able to reflect this behaviour, because they do not care if memory is shared
or not. Im not 100% sure on this, but I think that I have observered this
behavior some time ago.

So the WorkingSet or Virtual Size will increase for each process, even if
the underlying pages are shared by the Memory Manager.

But remember that each Dll should have its own Base-Address set, otherwise
the nessersary Relocations would make many pages to be written by the
Loader. This would result in not-sharable pages! So check your Base-Address
settings (Project Properties/Build Tab).

> The assemblies I'm testing with are not large.  Combined they are
> about 600K in size (size of the DLL files).

Because Processes execution managed code have a higher memory footprint
"by-design", most likely the difference will not be very big.

> Is there some overhead in
> using nGen which increases memory usage by about the same amount as
> I'm saving in this case or something?

Maybe. Maschine-Code is usually greater in size than IL. Of cause the JIT
Compiler (for example system.dll = 3.018.752, system.ni=8.093.696).

When a process loads the managed system.dll, the _virtual_ memory will
increase for the size of the system.dll (there is actualy no phyisical
memory needed for this, because the memory-region is backed by the image
itself; only memory the pages that are accesses will be loaded from the
image into physical memory). When you call a method of the system.dll (the
JIT Compiler works on method-basis), it will compile the IL "in-place",
which forces the OS to copy the affected Page(s) into the Paging-File (it
can no longer be shared).

When a process loads the native image system.il, the _virtuel_ memory will
also increase for the size of the image. But when no relocation (or
rebinding) is needed, this pages can be shared accross processes.

In both cases the _virtual_ memory will increase. The _virtual_ memory
needed to load the native image will be bigger that the virtual memory that
is required to load the managed assembly. But the physical memory needed
(eigher in "real" RAM, or paging file), will be higher when no native image
is used.

So: When you really want to analyse this in detail, Task-Manager may be not
the right tool for this job. You should least use a tool that is able to
provide better details about memory-allocation.

GP
Nick John - 02 Jul 2007 00:35 GMT
Gunter,

thanks for your reply.

> So the WorkingSet or Virtual Size will increase for each process, even if
> the underlying pages are shared by the Memory Manager.

Thanks for pointing out the obvious about virtual memory, I'm not sure how I
managed to overlook that.

I switched to looking at the WS Private value (using Process Explorer) and
you are right I did see an improvement as long as I rebased them (my
DLLs/assemblies) before putting them in the GAC and NGen'ing them.

Thanks.

Process Explorer -
http://www.microsoft.com/technet/sysinternals/utilities/ProcessExplorer.mspx

Cheers,
Nick

> Hello Nick!
>
[quoted text clipped - 63 lines]
>
> GP

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.