views:

119

answers:

2

The memory leak is not happening on every machine, but reliably on a couple at my work, and it's looking like close to 10% in the field.

I have a product that uses a Windows service to monitor user input to launch alerts, paired with a visual application that serves only to sit in the system tray, and allow the user to make configuration changes.

I chose to use a remoted object to share the configuration information between the two processes. In the service it is called serviceConfig, and in the visual application it is called configData. The object is created on the server first, and then remoted as follows:

try
{
    InitializeComponent();
    setAppInitDLL(thisDirectory);
    serviceConfig = new serviceConfigData();
    Regex getVersion = new Regex("Version=(?<ver>[^,]*)");
    if (getVersion.IsMatch(Assembly.GetExecutingAssembly().FullName))
    {
        serviceConfig.Version = new Version(getVersion.Match(Assembly.GetExecutingAssembly().FullName).Result("${ver}").ToString());
    }
    // Create the server channel for remoting serviceConfig.
    serverChannel = new TcpServerChannel(9090);
    ChannelServices.RegisterChannel(serverChannel, false);
    RemotingServices.Marshal(this.serviceConfig, "ServiceConfigData");
    baseLease = (ILease)RemotingServices.GetLifetimeService(serviceConfig);
    lock (Logger) { Logger.Write(String.Format("The name of the channel is {0}", serverChannel.ChannelName)); }

    lock (Logger) { Logger.Write("Exiting Constructor"); }
}
catch (Exception ex)
{
    lock (Logger) { Logger.Write(String.Format("Error in Constructor:{0}", ex.Message)); }
}

Then in the visual application I have a private object that I connect using:

configData = (serviceConfigData)Activator.GetObject(typeof(serviceConfigData), "tcp://localhost:9090/ServiceConfigData");

When reading or writing to this object, I have catch statements for Socket Exceptions and Remoting Exceptions which then call this same statement.

On most machines this works without leaking memory, but on some it leaks very quickly. All machines at work have .NET 3.5, some are XP, a couple are Vista. The problem has only been seen on XP machines, and the machines in the field are all XP.

Any ideas where I should be looking, and as a secondary question, should I be using something completely different from this?

A: 

My first thought would be to profile the application on the machines you're seeing the leak with something like Red Gate's Memory Profiler.

It'll be a lot more reliable than attempting to guess what the leak might be.

As for chosing the right technology, if all your machines will have .NET 3.5 installed you might want to consider migrating to WCF (primarily Named Pipes) for your inter-process communication. Check this SO post for more detail...

Justin Niessner
Struggling with .NET Memory Profiler right now, never used one before, and I'm seeing under Types/Resources it's all under Namespace/System: Kernel, Name/Resource:HeapMemory. When I select this it shows a rapidly growing number of instances. This appears to be in direct proportion to the number of times I use the get or set on any of the public parameters in the remoted object.
mlusby
Can't seem to find the problem, even with the memory profilers (probably due to my inexperience with them), moving to named pipes.
mlusby
A: 

I'd recommend to use YourKit .NET profiler http://www.yourkit.com/dotnet/ and capture heap memory snapshot when leak happen. After that you'll immediately find the reason of the leak by finding path from leaked object to garbage collector root. Here is the good article how to find memory leak .NET applications http://www.yourkit.com/docs/net45/help/memory%5Fleaks.jsp

--serge

Serge