views:

2594

answers:

5

I am working on a little bookmark managing app written in C#, using WPF. It just sits in the system tray and is idle 99% of the time. Recently I looked in the task manager and discovered that it uses around 25 megs of memory (and around 12 megs before it is activated for the first time) which I thought was a bit much for an app that does nothing most of the time. That made me wonder if there are any ways to reduce the memory usage by, e.g., disabling WPF features that are optional.

I have discovered one fact which might lead to something, though I don't know any way to leverage it. Threads in .NET take around one meg each, and it turns out my app uses around 6/12 threads (before and after being activate for the first time). This accounts for half my memory usage which is rather significant. I dont spawn any new threads directly, but I have no idea of how WPF, as well as other parts of .NET, uses threads for different tasks so I find it hard to do anything about it. Using events for stuff that is not directly related to the GUI, does this for example spawn new threads?

So I guess my question is twofold, how can you reduce the memory usage .NET/WPF applications in general and how can you minimize the number of threads being spawned? Note that I'm not so much thinking about small details such as those brought up in this answer, but rather how to design for low memory usage throughout your entire application.

+3  A: 

Unfortunately, in my experience, ~25MB is the lowest I've seen for small WPF apps I've made, at least on Windows XP. I think even the empty template WPF apps take ~20MB. What OS are you running on?

Windows Vista is a better story, and you can probably expect to see ~13-15MB for an empty template WPF app.

For your app to use 6-12 threads and only use ~25MB, I'd say you're doing pretty well. :-)

unforgiven3
I'm running Vista 64-bit. To be honest, it's not really something that I worry about too much. I mean, with current hardware prices, memory is practically free - it's almost feasible to bundle each copy of my program with a 2gb memory stick ;)
Morten Christiansen
You will worry about it if you are asked to optimize it on terminal services, server admin don't want to see 30 idle processes waste around 1GB ram.
Dennis Cheung
you will also worry when there are lots of other similar apps running, each one using lots of RAM. Its like the roads, build more roads and you just end up with more congestion, buy more RAM and you find your box still needs more.
gbjbaanb
You are, of course, right that I should not ignore the memory usage, and that is the reason for this post. But the particular app I'm building is just a little hobby project so it's not too bad. It does feel wrong, though, when such a small app uses that much memory.
Morten Christiansen
Yeah, I think you'll be okay - but if you test it on Windows XP, prepare to be shocked - I'm betting it will take a minimum of 60MB.
unforgiven3
+3  A: 

If it's a system tray app, you could have that part of the program implemented in WinForms (or even C++), and only spawn the WPF application when the user double-clicks your icon. That way, you only pay for the memory when you're actually using it.

Roger Lipscombe
+1  A: 

Not sure if this helps, but in MS Visual C++, the default stack size is 1 MB, and can be set to whatever you want using a compiler option. Obviously, C# apps inherited this default size (So each thread takes at minimum 1MB). But there doesn't seem to be anyway to set it when I do "csc /?"

Steve Hanov
A: 

It is a fact of .NET/Java applications that the CLR/JVM will allocate a larger heap memory then actually needed/used. They usually less willing to release allocated to OS unless OS is getting physical memory starveling.

But it is true that memory-management is a difficult topic. The problem is: how do you define the memory usage by your application? Total allocated virtual memory? total working-set? private working-set? used memory in heap? heap allocated? minimum, peak or average?

One thing you can do is using CLR Profiler to check are there too much heap allocated. You can try to optimize it by spend memory consuming takes by times to prevent the heap glow too much.

Dennis Cheung
+1  A: 

Ultimately, what you really care about, is the private working set. Thats the real figure that matters.

dhopton