.NET Remoting Syntax memory leak, TCP, Marshal by reference

I use the simplest example of remote interaction that I could find, sharing an object between a Windows service and a Windows Forms (client) program running on the same computer.

The service creates an instance of the object as follows:

serviceConfigRemote = new serviceConfigDataRemote(); serverChannel = new TcpServerChannel(9090); ChannelServices.RegisterChannel(serverChannel, false); RemotingServices.Marshal(this.serviceConfigRemote, "ServiceConfigData"); 

The client establishes a connection as follows:

 TcpClientChannel channel = new TcpClientChannel(); ChannelServices.RegisterChannel(channel, false); configData = (serviceConfigDataRemote)Activator.GetObject(typeof(serviceConfigDataRemote), "tcp://localhost:9090/ServiceConfigData"); 

The idea is that the service can make changes to some parameters of the object so that the client can read these changes.

Object itself:

 public sealed class serviceConfigDataRemote : MarshalByRefObject { private bool myConnectedFlag; private bool mySendingFlag; private bool myUpdateFlag; private string myClientConfiguration; static readonly serviceConfigDataRemote instance = new serviceConfigDataRemote(); static serviceConfigDataRemote() { } public serviceConfigDataRemote() { myConnectedFlag = false; mySendingFlag = false; myUpdateFlag = false; myClientConfiguration = ""; } public static serviceConfigDataRemote Instance { get { return instance; } } public override object InitializeLifetimeService() { return (null); } public bool Connected { get { return myConnectedFlag; } set { myConnectedFlag = value; } } public bool Sending { get { return mySendingFlag; } set { mySendingFlag = value; } } public bool CheckForUpdates { get{return myUpdateFlag;} set { myUpdateFlag = value; } } public string ClientConfiguration { get { return myClientConfiguration; } set { myClientConfiguration = value; } } } 

While the service is running on its own, the use of Mem in the task manager remains constant, although the service constantly updates the object with status information. When the client starts up, both begin to grow in Mem Usage and never drop.

This is a problem that I mentioned in My Previous Question about detecting memory leaks.

It looks different on different machines, some do not show an increase in memory, but the machines that do this will reliably reproduce this problem. The launch of the .NET Memory Profiler shows that in the service an increasing number of “new instances” has only one or two “Deleted” in the “Types / Resources” tab, where “namespace” / “System” is the kernel and “name / resource "-" HeapMemory ". I'm still trying to find out how to use Memory Profiler, so I apologize if this is the wrong information and tell me where else should I look. Will also be appreciated.

This object is created once, with only a few parameters for reading and writing, without the io file, without allocating the memory that I see, and yet my memory usage appears only at the moment when I start connecting with the client to this object and read its meanings. Any and all input will be appreciated, as I would like to avoid pulling this code and replacing it with named pipes or similar, but I am quickly approaching this point as the only option.

+6
c # memory-leaks marshalling remoting
source share
3 answers

It should not be where your service instantiates an object,

 serviceConfigRemote = new serviceConfigDataRemote(); 

look like

 serviceConfigRemote = serviceConfigDataRemote.Instance; 

instead

At least the way you do this, you create two different instances on the server side, one in the static instance element that will be used by the instance property, and the other through new serviceConfigDataRemote() Explicit build. It can also help you add a private constructor to this class so that nothing can create a singleton instance other than a static initializer.

This may not be a solution to ever-growing memory, but it seems to be a problem to solve the problem.

EDIT:

Here are some more tips I found while cleaning up the network:

  • Add [MTAThread] to the main service main method.
  • RemotingServices.Disconnect(this.serviceConfigRemote); when you terminate the host service.

Hope this helps.

+3
source share

You tried using the lazy instance on your Singleton. You may not like the way you create it.

  public sealed class serviceConfigDataRemote: MarshalByRefObject
     {
         private bool myConnectedFlag;
         private bool mySendingFlag;
         private bool myUpdateFlag;
         private string myClientConfiguration;

         static serviceConfigDataRemote instance;

         static serviceConfigDataRemote ()
         {
         }

         public serviceConfigDataRemote ()
         {
             myConnectedFlag = false;
             mySendingFlag = false;
             myUpdateFlag = false;
             myClientConfiguration = "";
         }

         public static serviceConfigDataRemote Instance
         {
             get
             {
                 if (instance == null)
                 {
                     lock (new Object ())
                     {
                         if (instance == null)
                         {
                             instance = new serviceConfigDataRemote ();
                         }
                         return instance;
                     }
                 }
                 return instance;
             }
         }

         public override object InitializeLifetimeService ()
         {
             return (null);
         }


         public bool Connected
         {
             get {return myConnectedFlag;  }
             set {myConnectedFlag = value;  }
         }

         public bool Sending
         {
             get {return mySendingFlag;  }
             set {mySendingFlag = value;  }
         }

         public bool CheckForUpdates
         {
             get {return myUpdateFlag;  }
             set {myUpdateFlag = value;  }
         }

         public string ClientConfiguration
         {
             get {return myClientConfiguration;  }
             set {myClientConfiguration = value;  }
         }
     }
+1
source share

Since the only OS in which you see this error is XP, there are several possible problems.

  • XP has an incoming connection limit of 10 (in pro) or 5 (at home), and this can play a role in the problem.

  • Make sure all service packs / patches are installed. I know that this can be commonplace and cliche for any problems, but the fact that this problem only appears in XP implies that it is related to the OS.

Also, I’m not sure how you use the service, but Windows XP is a desktop OS, not a server OS. If you assume that the service is a server of any type, you really should use 2000/2003/2008, etc., especially since it only has problems with XP.

0
source share

All Articles