[Mono-bugs] [Bug 59624][Cri] New - Remoting over HTTP creates new thread for each request.
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Fri, 4 Jun 2004 23:20:32 -0400 (EDT)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by ryoung@novell.com.
http://bugzilla.ximian.com/show_bug.cgi?id=59624
--- shadow/59624 2004-06-04 23:20:32.000000000 -0400
+++ shadow/59624.tmp.4250 2004-06-04 23:20:32.000000000 -0400
@@ -0,0 +1,407 @@
+Bug#: 59624
+Product: Mono: Runtime
+Version: unspecified
+OS:
+OS Details:
+Status: NEW
+Resolution:
+Severity: 001 One hour
+Priority: Critical
+Component: misc
+AssignedTo: mono-bugs@ximian.com
+ReportedBy: ryoung@novell.com
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: Remoting over HTTP creates new thread for each request.
+
+Please fill in this template when reporting a bug, unless you know what you
+are doing.
+Description of Problem:
+
+With the beta 2 release of Mono. When remoting over an http channel every
+request causes a thread to be spun. This is exposing a memory leak. As
+you make request you will see memory gradualy grow until no memory is
+available. If you run the server in memprof you will see a thread start
+before every request. This is causing the iFolder memory leak.
+
+The following code will reproduce the problem.
+
+using System;
+
+using System.IO;
+
+using System.Diagnostics;
+
+using System.Runtime.Remoting.Messaging;
+
+using System.Collections;
+
+using System.Runtime.Remoting;
+
+using System.Runtime.Remoting.Channels;
+
+using System.Runtime.Remoting.Channels.Http;
+
+using System.Runtime.Remoting.Channels.Tcp;
+
+using System.Runtime.Remoting.Activation;
+
+
+
+namespace RemotingTest
+
+{
+
+ public class ChannelSetup
+
+ {
+
+ private const string channelName = "RTestChannel";
+
+ static public bool tcp = false;
+
+ //static public bool tcp = true;
+
+
+
+ /// <summary>
+
+ /// Method to register a client channel.
+
+ /// </summary>
+
+ public static void RegisterClientChannel(string server)
+
+ {
+
+ Hashtable props = new Hashtable();
+
+ props["port"] = 8352; //serviceUri.Port;
+
+ props["name"] = channelName;
+
+
+
+ BinaryClientFormatterSinkProvider
+
+ clientSink = new BinaryClientFormatterSinkProvider();
+
+
+
+ if (tcp)
+
+ {
+
+ ChannelServices.RegisterChannel(new TcpClientChannel(props, clientSink));
+
+ }
+
+ else
+
+ {
+
+ ChannelServices.RegisterChannel(new HttpClientChannel(props, clientSink));
+
+ }
+
+ //RemotingConfiguration.RegisterActivatedClientType(typeof(Factory),
+string.Format("Http://{0}:8352", server));
+
+ //RemotingConfiguration.RegisterWellKnownClientType(new
+WellKnownClientTypeEntry(typeof(Factory),
+string.Format("tcp://{0}:8352/RemotingTest", server)));
+
+ }
+
+
+
+ /// <summary>
+
+ /// Method to register the server channel.
+
+ /// </summary>
+
+ public static void RegisterService()
+
+ {
+
+ Hashtable props = new Hashtable();
+
+ props["port"] = 8352; //serviceUri.Port;
+
+ props["name"] = channelName;
+
+
+
+ BinaryServerFormatterSinkProvider
+
+ serverSink = new BinaryServerFormatterSinkProvider();
+
+
+
+#if !MONO
+
+ serverSink.TypeFilterLevel =
+
+ System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
+
+#endif
+
+ if (tcp)
+
+ {
+
+ ChannelServices.RegisterChannel(new TcpServerChannel(props, serverSink));
+
+ }
+
+ else
+
+ {
+
+ ChannelServices.RegisterChannel(new HttpServerChannel(props, serverSink));
+
+ }
+
+ //RemotingConfiguration.RegisterActivatedServiceType(typeof(Factory));
+
+ //RemotingConfiguration.RegisterWellKnownServiceType(new
+WellKnownServiceTypeEntry(typeof(Factory), "RemotingTest.rem",
+WellKnownObjectMode.Singleton));
+
+ }
+
+ }
+
+
+
+ class Class1
+
+ {
+
+ /// <summary>
+
+ /// The main entry point for the application.
+
+ /// </summary>
+
+ [STAThread]
+
+ static void Main(string[] args)
+
+ {
+
+ if (args.Length < 1)
+
+ Console.WriteLine("Usage: {0} [C(lient) ServerIP | S{erver)]",
+System.Reflection.Assembly.GetExecutingAssembly());
+
+
+
+ if (args[0].StartsWith("C"))
+
+ {
+
+ new Client(args[1]);
+
+ }
+
+ else if (args[0].StartsWith("S"))
+
+ {
+
+ ChannelSetup.RegisterService();
+
+ RemotingServices.Marshal(new Factory(), "RemotingTest.rem");
+
+ Console.WriteLine("Press Enter to exit.");
+
+ Console.ReadLine();
+
+ }
+
+ }
+
+ }
+
+
+
+ public class Client
+
+ {
+
+ public Client(string server)
+
+ {
+
+ ChannelSetup.RegisterClientChannel(server);
+
+ Console.WriteLine("Starting.");
+
+ Factory f;
+
+ if (ChannelSetup.tcp)
+
+ {
+
+ f = (Factory)Activator.GetObject(typeof(Factory),
+string.Format("tcp://{0}:8352/RemotingTest.rem", server));
+
+ }
+
+ else
+
+ {
+
+ f = (Factory)Activator.GetObject(typeof(Factory),
+string.Format("http://{0}:8352/RemotingTest.rem", server));
+
+ }
+
+ //Factory f = new Factory();
+
+ while (true)
+
+ {
+
+ Server s = f.GetServer();
+
+ byte[] data;
+
+ data = s.GetData();
+
+ Console.WriteLine("Got {0} bytes of data.", data.Length);
+
+ s.PutData(data);
+
+ Console.WriteLine("Put {0} bytes of data.", data.Length);
+
+ }
+
+ }
+
+ }
+
+
+
+ public class Server : MarshalByRefObject
+
+ {
+
+
+
+ byte[] data;
+
+ public Server()
+
+ {
+
+ data = new byte[128 * 1024];
+
+ for (int i = 0; i < data.Length ; i++)
+
+ data[i] = (byte)(i); // % Byte.MaxValue);
+
+ }
+
+
+
+ /// <summary>
+
+ /// This will be used as a singleton do not expire the object.
+
+ /// </summary>
+
+ /// <returns>null (Do not expire object).</returns>
+
+ public override Object InitializeLifetimeService()
+
+ {
+
+ return null;
+
+ }
+
+
+
+ public byte[] GetData()
+
+ {
+
+ Console.WriteLine("Getting {0} bytes of data.", data.Length);
+
+ return data;
+
+ }
+
+
+
+ public void PutData(byte[] data)
+
+ {
+
+ Console.WriteLine("Put {0} bytes of data.", data.Length);
+
+ }
+
+ }
+
+
+
+ public class Factory : MarshalByRefObject
+
+ {
+
+ /// <summary>
+
+ /// This will be used as a singleton do not expire the object.
+
+ /// </summary>
+
+ /// <returns>null (Do not expire object).</returns>
+
+ public override Object InitializeLifetimeService()
+
+ {
+
+ return null;
+
+ }
+
+
+
+ public Server GetServer()
+
+ {
+
+ return new Server();
+
+ }
+
+ }
+
+}
+
+
+
+
+Steps to reproduce the problem:
+1. Run the attached program as follows "memprof mono RemotingTestServer.exe S"
+2.The Run the client as follows "mono RemotingTestServer.exe C localhost"
+3. Watch the threads come and go.
+4. If you rebuild the test over tcp this does not happen.
+
+Actual Results:
+
+
+Expected Results:
+
+
+How often does this happen?
+
+Every time.
+
+
+Additional Information: