views:

187

answers:

8

I have a windows service that do something periodically. on user account runs systray application (written in C#) that communicate with windows service (thru .net remoting) and shows a status and some option to users.

Everything works well beside that systray app uses 20-30MB of RAM ! it have to work in terminal environment, when 50 users login, only systray apps take >1GB of RAM ! and i don't have to add, that's wrong :)

Is it possible to write .net systray application that will be small ? (1-2MB max?) or should I write it in c/c++? then, what kind of communication should I use between windows service (written in C#) and systray app ?

+1  A: 

It's most likely that the memory usage issues you are experiencing are specific to your application, rather than all sys-tray apps built with .NET.

You should profile your application to determine where the large memory usage is happening.

Andy Holt
+1  A: 

Another consideration is that a lot of memory consumed by .NET apps is in shared (.NET) dlls, and will not duplicate when multiple instances are run (unless the OS uses randomized dll load addresses).

You can also reduce the memory used by JIT compiling by installing your assemblies to the GAC and pre-JITting them using ngen. Again, this will result in reduced memory usage unless the OS randomizes dll load addresses.

Stephen Cleary
Application have references only to System.* libraries. Application consist only from one class and few small icons.It changes icons in systray, changes tooltip and show small context menu.On my computer (vista) process explorer tells me 'Address space load randomization: enabled' is this feature is useful? or it only takes more memory from OS ?
razor
ASLR is useful from a security perspective, but does impact memory usage.
Stephen Cleary
I'm pretty sure ASLR is off for .NET ngen-ed images. Editbin.exe /dynamicbase if you really want to make sure.
Hans Passant
They [turned it on](http://msdn.microsoft.com/en-us/magazine/dd569747.aspx) as of .NET 3.5 SP1, and I just checked a .NET 4 project using `dumpbin my.exe /headers`. It was on ("Dynamic base" shows up under "DLL characteristics").
Stephen Cleary
So, if i decide to write systray app in c/c++what kind of communication should I use between windows service (written in C#) and systray app ?
razor
There are a couple of options: named pipes are probably easiest; TCP/IP sockets would also work.
Stephen Cleary
A: 

Your sys-tray application is probably having memory leaks. A good profiling tool can help you understand what's happening.

Edin Dazdarevic
there is no memory leaks (memory footprint doesn't grow).it's totally simple app - just shows context menu:http://i50.tinypic.com/sxku0x.jpgand it takes ~13MB of RAMso I assume that i can't create small (<2MB) systray application in .net :/
razor
A: 

So, if i decide to write systray app in c/c++ what kind of communication should I use between windows service (written in C#) and systray app ?

razor
A: 

We faced similar problem in past and I'd share my solution with you.

.Net framework TCP/IP library is pathetically under-performing and eats up memory like anything.

As solution to this we opted to to XF library from KODART an open-source high-performance TCP/IP library for .Net applications. It scales amazingly on multiple client connections.

You can establish TCP/IP channels using XF library and observe the results yourself.

Checkout this article for additional information.

this. __curious_geek
A: 

The release of WCF (.NET 3.0 or 3.5?) rendered .NET remoting obsolete. With WCF you have the option of hosting a WCF server in your Windows service and then communicate with your service through TCP/IP. In my experience WCF is far more stable than .NET remoting.

Depending on your needs you may want to consider using ServiceController instead of remoting or WCF. With ServiceController you can start and stop services and you can also send application defined commands (as integers) to your service using Service.Controller.ExecuteCommand. Using ServiceController is a lot simpler than remoting and WCF but not as flexible.

Jakob Christensen
A: 

If all you need is change icons in systray, change tooltip and show small context menu, by all means write your systray app in C/C++ using bare WinAPI, and use a message-mode named pipe to communicate with the service. Don't forget to use the Global\ pipe name prefix to allow systray apps running in multiple sessions to connect to the same service.

Anton Tykhyy
+1  A: 

I've added following line to my code (app calls it sometimes along with GC.Collect() )

System.Diagnostics.Process.GetCurrentProcess().MaxWorkingSet =
                System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet;

Memory usage dropped to ~2MB (from 15-25MB), after nulling some objects after use (drawing menu and icon), memory usage dropped to ~540KB ! it grows a little (to ~2-3MB if I use context menu, but then it drops back to ~540KB)

So, goal achieved :)

razor