[Mono-bugs] [Bug 78306][Wis] New - CompressedStack causes continuous slowdown / excessive memory usage

bugzilla-daemon at bugzilla.ximian.com bugzilla-daemon at bugzilla.ximian.com
Fri May 5 10:04:03 EDT 2006


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 horst.reiterer at mind-breeze.com.

http://bugzilla.ximian.com/show_bug.cgi?id=78306

--- shadow/78306	2006-05-05 10:04:03.000000000 -0400
+++ shadow/78306.tmp.20832	2006-05-05 10:04:03.000000000 -0400
@@ -0,0 +1,142 @@
+Bug#: 78306
+Product: Mono: Class Libraries
+Version: 1.1
+OS: other
+OS Details: Red Hat Enterprise Linux 4
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Wishlist
+Component: CORLIB
+AssignedTo: mono-bugs at ximian.com                            
+ReportedBy: horst.reiterer at mind-breeze.com               
+QAContact: mono-bugs at ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: CompressedStack causes continuous slowdown / excessive memory usage
+
+The test case below (client.cs, server.cs), a simple HTTP client / server
+scenario is affected by an issue in the CompressedStack implementation.
+With an increasing uptime, the rate of processed requests decreases
+dramatically. At the same time, the memory consumption of the server
+process approaches unacceptable levels, the heap grows constantly.
+
+The problem is caused by CompressedStack.Capture, which reads the current
+security stack via SecurityFrame.GetStack, appends the CompressedStack list
+of Thread.CurrentThread.GetCompressedStack and returns the result. As a
+result, the list grows with every Capture performed without any cleanup
+taking place.
+
+The problem can be worked around (not fixed) with a trivial patch (see
+attachments) that causes CompressedStack.Capture not to append
+Thread.CurrentThread.GetCompressedStack. Certainly, this change breaks the
+functionality but solves the issue for the included testcase.
+
+Credits go to Hannes Mahringer for profiling the testcase and creating the
+attached patch.
+
+Steps to reproduce the problem:
+1. Run server.exe
+2. Run client.exe
+3. Monitor the decreasing request rate as well as the
+   memory consumption of the process.
+
+Actual Results:
+
+Within 12 hours of uptime, the request rate decreased from 500 to 1-2
+requests per second. Additionally, the server process virtual memory and
+RSS increased continuously, both reached unacceptable levels.
+
+501      23934 99.4  5.4 1609612 901692 pts/4 Sl  00:10 610:16
+  mono --optimize=all,-ssapre --server server.exe
+501      24041  0.8  0.0 31968 10308 pts/4   Sl+  00:11   5:10
+  mono --optimize=all,-ssapre --server client.exe
+
+Expected Results:
+
+A more or less constant response rate and memory consumption. With the
+attached patch, the issue can be solved in respect to the testcase, but it
+certainly does not represent the correct solution.
+
+How often does this happen? 
+
+100 out of 100 times
+
+Additional Information:
+
+The following testcase comprised of a client and server executable can be
+used to reproduce the problem.
+
+client.cs:
+
+using System;
+using System.IO;
+
+public class Client
+{
+  public static void Main()
+  {
+    Uri uri = new Uri("http://localhost:8080/");
+    byte[] buf = new byte[100];
+
+    while (true) {
+      WebRequest req = WebRequest.CreateDefault(uri);
+      req.Method = "POST";
+      req.ContentLength = buf.Length;
+
+      Stream stream = req.GetRequestStream();
+      stream.Write(buf, 0, buf.Length);
+      stream.Close();
+
+      WebResponse response = req.GetResponse();
+      response.Close();
+    }
+  }
+}
+
+server.cs:
+
+using System;
+using System.IO;
+using System.Net;
+using System.Threading;
+
+public class Server
+{
+  public static void Main()
+  {
+    HttpListener listener = new HttpListener();
+    listener.Prefixes.Add("http://localhost:8080/");
+    listener.Start();
+
+    byte[] buf = new byte[100];
+    long start = DateTime.UtcNow.Ticks;
+    int count = 0;
+
+    while (true) {
+      HttpListenerContext ctx = listener.GetContext();
+      Stream stream = ctx.Request.InputStream;
+      stream.Read(buf,0,100);
+      stream.Close();
+
+      HttpListenerResponse response = ctx.Response;
+      response.StatusCode = 200;
+      response.ContentLength64 = 0;
+
+      Stream outputStream = response.OutputStream;
+      outputStream.Write(buf, 0, 0);
+      outputStream.Close();
+      response.Close();
+
+      long end = DateTime.UtcNow.Ticks;
+      count++;
+
+      if (end - start >= 10000000L)  {
+        Console.WriteLine("Requests/s: " + count);
+        start = end;
+        count = 0;
+      }
+    }
+  }
+}


More information about the mono-bugs mailing list