The Jeff

The thoughts, concerns and major upheavals of Jeff Berg

Services, Memory & the big head

Overhead that is...

Well I have working on a small little project in my spare time that needed a Windows Service. So I made one. Wooopideee doo, how easy the .Net Framework makes life. Well after I get it running and all I see that my very small Windows Service is taking up 15 MB of RAM!!!. WHAT??? No way... So I go ahead and remove all of the references to my code and recompiled. 12MB...well that seems a bit large for nothing. So I did some research, durring this research I found a really good search engine to find things .net related right here. (shhh it's our little secret). All in all I found out that I am not familiar with the inner workings of .net (YET!!!), so I am glad there are so people could answer my question and this little ladies question with this code:

public class MemoryManagement
{
      private MemoryManagement() {}

      [System.Runtime.InteropServices.DllImport ("kernel32.dll")]
      private extern static int SetProcessWorkingSetSize (IntPtr hProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

      public static void SwapOutProcess() 
      {
     
GC.Collect();
     
GC.WaitForPendingFinalizers();
     
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
           
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
      }
}

Yahoo, this cut down my service in half. Now it is 7-8MB. I will see how large it is in the morning. Hope my pain could help someone else.

Oh and 7MB still isn't preferable, anyone know of a way to cut it down more?

Comments

Jeff Gonzalez said:

I was worrying about this same thing at one point. Someone told me it was worthless to worry about what task manager shows me as memory utilization. This person also told me it was useless to worry about working set allocation. A working set is just so your application has enough memory reserved to start up. It doesn't actually mean you are using that much memory. If the OS needs more, it will query processes that have excess working sets, and it will trim it down itself. You really don't need to worry about it. Secondly, you should really NEVER EVER have a reason to call GC.Collect(). It is enormously ezpensive since it forces garbage collection. All of the memory you saved by trimming down your working set was just offset by the huge processor and memory spike for calling a garbage collection.

See Rico Mariani's blog for more details...
http://blogs.gotdotnet.com/ricom/PermaLink.aspx/5ce9cc25-7698-418e-b266-24397e5376c7
# November 19, 2003 11:44 PM

Jeff Gonzalez said:

Just to add further, if you really would like to demonstrate this to yourself. Create a winform app, with absolutely no controls on it, start it and then look at memory. It will be around 10-15,000K. Minimize it, and look at your memory again, less than a 1,000K now. If you bring it back up one more time, it will be sitting at about 1.5MB prolly. As I understand it, you are never actually using that much memory, you just have it reserved.
# November 19, 2003 11:48 PM

denny said:

folks seem to be stuck with the world of WIn32/COM/C and when you use a tool built for that to measure a .Net assembly it will not give you accurate results.

1) your app is not a "classic" win32 app.
2) the allocated "working set" should be evaluated from the .net side of things to get the right info.
3) .Net uses a *DIFFERENT* allocation system than C/COM did.
4) .Net has to have space to JIT
5) .Net is doing all that from "Inside" a WIn32 allocation request.

think about this: it loads the meta-data, the msil code, it allocates a private heap for your apps managed memoery pool, it allocates space for the jited msil to be stored and executed as x86 opcodes
it tries to keep the number of Win32 memory calls down to a minimum for overhead and address fragmentation reasons.
if it needs to it will re-size its working set on-the fly.
how much of that space is "requested address space" and howmuch is "allocated and written to" ??
have you ran any of the .net profilers to find out??

I bet the 7megs is the "real" working size and by shrinking the ws-size you will force a win32 alloc to re-expand it if any largeish memory calls havpen in the .net side -- like adding some new strings to the string pool....

you are running in a VM that classic WIndows tools *DO NOT UNDERSTAND* and *CANNOT PROFILE*
to tune your app start with .net tools find out what the .net side is doing then see if you need to intervene.

PS: when your app compiles to MSIL it makes a "guess" at the runtime memory needed based on your apps calls and allocs.... that is also impacted by the libararys you reference.....
and a WIn32 Service has a COm Interop layer built in
so a healkthy chunbk of that 7megs is the CCW and RCW overhead to thunk from .net to COM and back....


# November 20, 2003 11:30 AM

Scott Galloway said:

Take a look at the .NET Memory profiler (http://www.scitech.se/memprofiler/), free trial and gives a pretty good idea of the memory usage of various bits of your app...
# November 20, 2003 12:23 PM

~JOSh-X said:

Wow... you are one cool blogger. This is the first time I've typed blogger. Well, second now.

<span title="isn't it hard to be... nothing important...">~JOSh-X</span>
# November 20, 2003 4:29 PM

TrackBack said:

More Information and VB.net code from AddressOf.com
# November 20, 2003 4:33 PM

TrackBack said:

Just a freak who links to me
# November 20, 2003 4:36 PM

The Jeff said:

Thanks for the enlightment, that is what I was looking for, but I thought If I put this up some smart people would tell me that this was wrong and why.

This community is GRRRRRRRRREAT!!!

The Jeff
# November 20, 2003 4:38 PM

TrackBack said:

^_^,Pretty Good!
# April 10, 2005 4:39 AM

kopibrandwiyzpn@mail.com said:

ヲタクも親しみを持ちやすかったんだろう。

# December 11, 2012 5:53 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)