Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / mcr-test / WWW / User / Introduction / performance.html
diff --git a/JMCR-Stable/mcr-test/WWW/User/Introduction/performance.html b/JMCR-Stable/mcr-test/WWW/User/Introduction/performance.html
new file mode 100644 (file)
index 0000000..cb01367
--- /dev/null
@@ -0,0 +1,538 @@
+<HTML>\r
+<HEAD>\r
+  <!-- Created by GNNpress/1.2 -->\r
+  <!-- Changed by: Anselm Baird-Smith,  4-Feb-1997 -->\r
+  <TITLE>Jigsaw performance evaluation</TITLE>\r
+</HEAD>\r
+<BODY BGCOLOR="white">\r
+<P>\r
+<A HREF="../../../" TARGET="_top_"><IMG BORDER="0" SRC="/icons/WWW/w3c_home"\r
+    ALT="W3C" WIDTH="72" HEIGHT="48"></A>\r
+<A HREF="http://www.w3.org/pub/WWW/Jigsaw/" TARGET="_top_"><IMG SRC="/icons/jigsaw" WIDTH="212"\r
+    HEIGHT="49" ALT="Jigsaw" BORDER="0"></A>\r
+<P>\r
+  <HR>\r
+<P>\r
+<IMG SRC="/icons/32x32/caution.gif" ALT="WARN !" BORDER="0" WIDTH="32"\r
+    HEIGHT="32"> This page has not be updated since the 1.0alpha3 release, we\r
+do plan to do so real soon, stay tuned. To get some ideas as to how\r
+<B>Jigsaw</B> compares to a C based HTTP server, you may want to check the\r
+<A HREF="http://www.w3.org/Protocols/HTTP/Performance/Pipeline.html">HTTP\r
+Performance Paper</A> (which, even though not exactly on the same subject,\r
+provides a fair idea of relative performances).\r
+<P>\r
+  <HR>\r
+<H1>\r
+  Performance Evaluation\r
+</H1>\r
+<P>\r
+This document describes the current performance achieved by <B>Jigsaw</B>,\r
+and compare them to other servers. This paper is not intended to prove that\r
+<B>Jigsaw</B> is the fastest server (which it is not), it just tries to point\r
+out that writing a server in Java is a reasonable thing to do.\r
+<P>\r
+The second section of this document will describe the current bottlenecks,\r
+and hilight some of the possible work arounds (which will hopefully be included\r
+in the next <B>Jigsaw</B> release).\r
+<H2>\r
+  Numbers\r
+</H2>\r
+<H3>\r
+  Caveat\r
+</H3>\r
+<P>\r
+Benchmarking HTTPD servers is definitely a difficult task. They are at least\r
+two difficulties here:\r
+<UL>\r
+  <LI>\r
+    The configuration of the server to benchmark,\r
+  <LI>\r
+    The test-suite used to run the benchmark.\r
+</UL>\r
+<P>\r
+The benchmark will usually depend on things such as your hardware and your\r
+system, but also, the load of the machine you are using for the benches,\r
+the kind of filesystem the server runs in (is it NFS, AFS, does it uses some\r
+automounter ?), and a number of other parameters that are difficult to measure.\r
+The numbers we will give in this section have all been obtained under the\r
+same global configuration. This is a SunSparcstation 5, 64Mb of RAM, running\r
+solaris2.5, all files are served through a read/write AFS volume. I am probably\r
+lacking a number of interesting parameters in the latter description, that's\r
+why I will focus on relative numbers (i.e. how <B>Jigsaw</B> performs relatively\r
+to other servers), rather then absolute numbers. You shouldn't even try to\r
+scale these numbers in any ways: some servers speedup won't be linear with\r
+the power of the machine it runs on (e.g. if server foo is 2 times faster\r
+then server bar on a sparc station 5, the relative performance of foo and\r
+bar on a sparc 20 may not be the same).\r
+<P>\r
+How are these numbers collected ? The number we will present are <I>by no\r
+mean</I> related to what a typical server will experience in some real life\r
+conditions. For example, in our benchmarks, the client and the server programs\r
+are always run on the same machine. This probably affect the request rate,\r
+however, it still gives us a good indication of the CPU consumption of the\r
+server, which is what we are really interested in. To collect these numbers,\r
+we have used the ptester program which is a simple C hitter provided with\r
+the <A HREF="http://www.signum.se/phttpd/">phttpd server</A>.\r
+<H3>\r
+  The benchmarks\r
+</H3>\r
+<P>\r
+For each of the servers we measure, we run the following four benchmarks:\r
+<DL>\r
+  <DT>\r
+    Single document retreival\r
+  <DD>\r
+    This first bench gets the same document in sequence, and prints out the number\r
+    of requests achieved for a given duration of time. For those of you familiar\r
+    with ptester, the command line is as follows:<BR>\r
+    <VAR><CODE>ptester -t60 &lt;document&gt;</CODE></VAR><BR>\r
+    We run this bench in two variants: first with a 4kb file(1.a) and 40kb file\r
+    (1.b)\r
+  <DT>\r
+    Multiple document retreival\r
+  <DD>\r
+    The second bench puts a little more load on the server, by requesting three\r
+    documents in parallel. The three documents are respectively of 4kb, 10kb\r
+    and 40kb. For those of you familiar with ptester, the command line is as\r
+    follows:<BR>\r
+    <CODE>ptester -t60 -rN &lt;doc1&gt; &lt;doc2&gt;\r
+    &lt;doc3&gt;</CODE><BR>\r
+    We run this benchmark in two variants: first with N=2 (2.a) 2 simultaneous\r
+    hitters for each document, for a total of 6 simultaneous request flows and\r
+    with N=10 (2.b) for a total of 30 simultaneous connections.\r
+  <DT>\r
+    Keep-alive enabled bench\r
+  <DD>\r
+    This last bench will only benefit to those servers that implement the HTTP\r
+    keep-alive feature. Each connection will be used to run multiple requests.\r
+    For those of you familiar with ptester, the command line is as follows:<BR>\r
+    ptester -t60 -kN &lt;document&gt;<BR>\r
+    The bench is only run for a single document of 4k, and for a <I>k</I> value\r
+    of 5, it is test 3.\r
+  <DT>\r
+    Long live bench\r
+  <DD>\r
+    This is to measure (or get some idea at least) the impact &nbsp;of the Java\r
+    garbage collector on <B>Jigsaw</B>. It's a replay of test 2 for a duration\r
+    of ten minutes, which give us our final benches 4.a and 4.b\r
+</DL>\r
+<H3>\r
+  Results\r
+</H3>\r
+<P>\r
+While running the benchmark, <B>Jigsaw</B> is configured to generate the\r
+appropriate (CommonLog) log files; no ident protocol is run.\r
+<P>\r
+We have obtained the following results:\r
+<P>\r
+<TABLE BORDER CELLPADDING="2">\r
+  <CAPTION ALIGN="Bottom">\r
+    Benchmark results in requests per second\r
+  </CAPTION>\r
+  <TR>\r
+    <TD></TD>\r
+    <TD>version</TD>\r
+    <TD>1.a</TD>\r
+    <TD>1.b</TD>\r
+    <TD>2.a</TD>\r
+    <TD>2.b</TD>\r
+    <TD>3</TD>\r
+    <TD>4.a</TD>\r
+    <TD>4.b</TD>\r
+  </TR>\r
+  <TR>\r
+    <TD><A HREF="http://www.w3.org/Daemon/">CERN-server</A></TD>\r
+    <TD>3.0</TD>\r
+    <TD>11</TD>\r
+    <TD>10</TD>\r
+    <TD>11</TD>\r
+    <TD>11</TD>\r
+    <TD>NA</TD>\r
+    <TD>11</TD>\r
+    <TD>10</TD>\r
+  </TR>\r
+  <TR>\r
+    <TD><A HREF="http://www.apache.org/">Apache</A></TD>\r
+    <TD>1.0.2</TD>\r
+    <TD>35</TD>\r
+    <TD>24</TD>\r
+    <TD>30</TD>\r
+    <TD>30</TD>\r
+    <TD>NA</TD>\r
+    <TD>33</TD>\r
+    <TD>30</TD>\r
+  </TR>\r
+  <TR>\r
+    <TD><A HREF="http://www.apache.org/">Apache</A></TD>\r
+    <TD>1.1.1</TD>\r
+    <TD>42</TD>\r
+    <TD>30</TD>\r
+    <TD>35</TD>\r
+    <TD>33</TD>\r
+    <TD>85</TD>\r
+    <TD>34</TD>\r
+    <TD>31</TD>\r
+  </TR>\r
+  <TR>\r
+    <TD><A HREF="http://www.signum.se/phttpd/">phttpd</A></TD>\r
+    <TD>0.99.70.1</TD>\r
+    <TD>46</TD>\r
+    <TD>37</TD>\r
+    <TD>39</TD>\r
+    <TD>38</TD>\r
+    <TD>4</TD>\r
+    <TD>39</TD>\r
+    <TD>37</TD>\r
+  </TR>\r
+  <TR>\r
+    <TD><B><A HREF="../../">Jigsaw</A></B></TD>\r
+    <TD>1.0alpha1</TD>\r
+    <TD>22</TD>\r
+    <TD>18</TD>\r
+    <TD>19</TD>\r
+    <TD>9</TD>\r
+    <TD>26</TD>\r
+    <TD>19(*)</TD>\r
+    <TD>8(*)</TD>\r
+  </TR>\r
+  <TR>\r
+    <TD><B><A HREF="../../">Jigsaw</A></B></TD>\r
+    <TD>1.0alpha3</TD>\r
+    <TD>22</TD>\r
+    <TD>18</TD>\r
+    <TD>19</TD>\r
+    <TD>18</TD>\r
+    <TD>26</TD>\r
+    <TD>19(*)</TD>\r
+    <TD>18(*)</TD>\r
+  </TR>\r
+</TABLE>\r
+<P>\r
+Due to some problems with the Java garbage collector, benches marked with\r
+a * have been run with 8 Mb of memory allocated to the Java interpreter rather\r
+than the default 1Mb, we'll come back to this.\r
+<P>\r
+Cells marked NA (not available) don't make sense for the given server (they\r
+don't support kepp-alive).\r
+<H2>\r
+  Lessons\r
+</H2>\r
+<P>\r
+A number of lessons can be deduced from the above performance numbers.\r
+Some&nbsp;of them are related to the current <B>Jigsaw</B> implementation,\r
+others are related to the current Java implementation.\r
+<P>\r
+All these lessons should be taken as hypothesis, only some experiments will\r
+tell the truth abouth these numbers.\r
+<H3>\r
+  <B>Jigsaw</B> implementation problems\r
+</H3>\r
+<P>\r
+Don't forget that <B>Jigsaw</B> current implementation is flaged as being\r
+<I>alpha</I>. This means a number of things, among which the fact that\r
+<B>Jigsaw</B> code has not yet been profiled and optimized. <B>Jigsaw</B>\r
+design should provide the basis of a fearly efficient httpd implementation.\r
+In particular, features such as authentication, logging, etc. which are not\r
+measured by the above benches should prove fearly efficient (the main reason\r
+for this assertion lies in the clever caching scheme <B>Jigsaw</B> uses for\r
+resource meta-informations).\r
+<P>\r
+However, what are the above numbers telling us ? First of all, benches 1.a\r
+and 1.b shows that <B>Jigsaw</B> throughput (the number of bytes/second it\r
+can emit) is not that bad. We did some experiments with a <I>native\r
+shuffler</I> to try to infer the cost of the actual file transmissions across\r
+the wire. This would run as follow: the Java part of the server would compute\r
+a reply, but would delegate the actual sending of the bytes to an efficient\r
+C multi-threaded process by using a Java native interface to the UNIX\r
+<CODE>sendmsg</CODE> system call. Although this gave us much better numbers\r
+on solaris 2.3, the results on solaris 2.5 were quite disapointing (the speed-up\r
+would totally disapear). The good news, however, is that the Java threaded\r
+IO performances are not that bad, and are probably not at this time the\r
+bottleneck. We do still, however, expect a significant boost in these number\r
+when the Java runtime will be able to use solaris native threads (although,\r
+at this stage, this should be taken as an intuition only).\r
+<H3>\r
+  As of 1.0alpha1\r
+</H3>\r
+<P>\r
+The real lesson from these numbers comes from the benches 2.a and 2.b.\r
+<B>Jigsaw</B> performance seems to be very sensitive to the number of\r
+<I>simultaneous</I> connections. After some quick investigation, our guess\r
+is that the main problem with the implementation is that it contains too\r
+many central resources, and that mutliple threads are mostly blocked trying\r
+to acquire them. At this point, we have detetected at least three of these:\r
+<DL>\r
+  <DT>\r
+    The <A HREF="../api/w3c.jigsaw.http.ClientPool.html">client pool</A>\r
+  <DD>\r
+    This object is the central part of the server: it dispatches incomming\r
+    connections to <I>client</I> objects which will then handle them. The current\r
+    implementation of the client pool has some nice features (for example, it\r
+    keeps a pool of threads, ready to run on behalf of any new incomming\r
+    connections). However it's current implementation locks the whole object\r
+    during the selection process of the client (which is poorly implemented right\r
+    now). This means that even if the server threads accept(2) connections as\r
+    fast as they arrive, it will block to acquire the lock on the client pool\r
+    before being able to dispatch the connection.\r
+  <DT>\r
+    The <A HREF="../api/w3c.tools.timers.EventManager.html">event manager</A>\r
+  <DD>\r
+    Before starting to read any incomming requests, client objects set a timer\r
+    in order to avoid maintaining idle connections for too long. Once the request\r
+    has been read and parsed, they then arm a second timer to control the duration\r
+    of the request processing. All these timers are set through a single event\r
+    manager, which is locked during both timers setting and timers cancelation.\r
+    To be more practical, if 10 simultaneous connections are made to the server,\r
+    then ten client objects will try to lock the event manager at the same time,\r
+    competing to acquire the appropriate lock.\r
+  <DT>\r
+    The <A HREF="../api/w3c.jigsaw.http.CommonLogger.html">logger</A>\r
+  <DD>\r
+    The logger is the central object in the server that logs all requests. As\r
+    for the above resources, deficiency in its current implementation (this logger,\r
+    for example, doesn't bufferize output) makes it a bottleneck.\r
+</DL>\r
+<P>\r
+Note that generally these bottlenecks exist only because the underlying\r
+implementation of the objects are not yet optimized (at this time, I don't\r
+think of them as being a design problem). To get an idea of how well\r
+<B>Jigsaw</B> would perform if these bottleneck were eliminated, I have put\r
+up together a version of <B>Jigsaw</B> that :\r
+<UL>\r
+  <LI>\r
+    Will no do any logging (that's easy, just undefine the <CODE>w3c.jigsaw.logger\r
+    property</CODE>)\r
+  <LI>\r
+    Will not register timeouts to the event manager (this makes sense since I\r
+    control the client side programs)\r
+</UL>\r
+<P>\r
+For the client pool, nothing simple can be done at this time. However, just\r
+with the two other optimizations, we already get &nbsp;28 requests/second\r
+for bench 2.a and 22 requests/second for test 2.b. The really interesting\r
+thing is to notice how the gap between these two numbers disappear (which\r
+means we really had cotention problems).\r
+<P>\r
+This is for the <B>Jigsaw</B> implementation. We hope that by the next release\r
+all these contention problems will be solved (the three above are on the\r
+top of the TODO list). However, as we mentioned in the preamble of this section,\r
+there is another set of problems related to the current Java implementation.\r
+<H3>\r
+  Jigsaw 1.0alpha3\r
+  <IMG BORDER="0" SRC="/icons/WWW/new_red" WIDTH="32" HEIGHT="14">\r
+</H3>\r
+<P>\r
+Most of the 1.0alpha1 bottlenecks have been reduced, here is a brief overview\r
+of what has happened to the three previous ones:\r
+<DL>\r
+  <DT>\r
+    The <A HREF="../api/w3c.jigsaw.http.ClientPool.html">client pool</A>\r
+  <DD>\r
+    Has been entirely rewritten. The new client pool tries to be pretty smart\r
+    by running in one of <I>four</I> modes:\r
+    <UL>\r
+      <LI>\r
+       The first mode is the light load mode. Under that mode, <B>Jigsaw</B> keeps\r
+       connection alive as much as longer as possible (with <I>no</I> timeout values,\r
+       or whatever).\r
+      <LI>\r
+       The second mode is normal load mode. When entering that mode, <B>Jigsaw</B>\r
+       closes one idle persistent connection before actually accepting a new one.\r
+       This ensures that <B>Jigsaw</B> doesn't run out of socket descriptors.\r
+      <LI>\r
+       The third mode is the high load mode. In that mode, <B>Jigsaw</B> inverses\r
+       thread priority: it lowers the accepting thread priority lower to the normal\r
+       client threads priority, so that client threads can perform there tasks faster\r
+       then connections are accepted.\r
+      <LI>\r
+       Finally, the last mode, called the <I>dead</I> mode is when <B>Jigsaw</B>\r
+       starts refusing connections.\r
+    </UL>\r
+  <DT>\r
+    The <A HREF="../api/w3c.tools.timers.EventManager.html">event manager</A>\r
+  <DD>\r
+    The event manager jobs has been reduced to keep track of requests that take\r
+    to long to request. Getting rid of the keep alive timeout has basically reduced\r
+    by half the load on the event manager.\r
+  <DT>\r
+    The <A HREF="../api/w3c.jigsaw.http.CommonLogger.html">logger</A>\r
+  <DD>\r
+    The logger now uses a n optional buffer, that speeds up the critical section\r
+    were it emits log entries.\r
+</DL>\r
+<P>\r
+It should also be noted that <B>Jigsaw</B> HTTP API has been totally redesign,\r
+and is much more efficient the the one included in 1.0alpha1.\r
+<P>\r
+The result of these changes is mainly seen through the much better handling\r
+of simultaneous connections that <B>Jigsaw</B> now provides.\r
+<H3>\r
+  Java implementation problems\r
+</H3>\r
+<P>\r
+Although Java comes from an old (well, at least three years old) project,\r
+its current implementation is still pretty new. They are a number of problems\r
+with this implementation that need serious work to be fixed.\r
+<P>\r
+First of all, let's start with the byte-code interpretation, since this is\r
+what people are the most scared with. As our numbers show, <B>Jigsaw</B>\r
+out-performs the CERN server by far, on nearly all benches (except for benches\r
+4.a and 4.b, which we will come to later). The CERN server is written in\r
+C. So at least, this proves that the interpretation overhead of Java can\r
+be dealt with by a <I>better design</I>. I would guess that even when JIT\r
+compilers come out that are able to speed up Java code by 10 times, compiling\r
+<B>Jigsaw</B> with them won't make it ten times faster, just because byte-code\r
+interpretation may not be the overhead in <B>Jigsaw</B>.\r
+<P>\r
+The most serious problems with the current JDK is that it doesn't come with\r
+the appropriate tools for profiling and detecting the hot-sopt in the server's\r
+code. The three bottlenecks that we have exhibited in the previous section\r
+were found by simply printing the thread statuses at various point in time\r
+under heavy load. Getting the right tools should help a lot optimizing\r
+<B>Jigsaw</B> implementation.\r
+<P>\r
+Another problem with the current Java implementation is the thread-safe\r
+libraries. If you use the StringBuffer class, for example, you will slow\r
+down your application because most of its methods are synchronized, while\r
+at some point, you know your thread is the only one dealing with some instances\r
+of this class. The StringBuffer class is the first concern here, since you\r
+usually want to write code such as:\r
+<PRE>String x = ... ;\r
+String y = ... ;\r
+String xy = x + y ;\r
+</PRE>\r
+<P>\r
+What really happens in the third line here, is that you implicitly allocate\r
+a StringBuffer instance, initially filled up with the content of string\r
+<CODE>x</CODE>, and then you append to it the content of string\r
+<CODE>y</CODE>. Then you get the StringBuffer as a String to get back the\r
+result that you assign to <CODE>xy</CODE>. Note only have you allocated a\r
+StringBuffer object, but you had to allocate a monitor for it (locking the\r
+global monitor cache for some time), and then call a synchronized method\r
+in order to do the concatenation. Depending on the conditions in which the\r
+above code is running you can work-around it by implementing your own\r
+concatenation operations in your object (this is what <B>Jigsaw</B> MIME\r
+parser does, for example).\r
+<P>\r
+Now, we still haven't exlpain the purpose and the result of benches 4.a and\r
+4.b. These are meant to see how the Java garbage collector react when its\r
+hosting application is under heavy load. [WARNING: following explanations\r
+are not bullet-proof, also they have good roots.]. The general garbage collection\r
+process of Java can be divided in a two step process:\r
+<OL>\r
+  <LI>\r
+    The garbage collector runs, and detect all the objects that are currently\r
+    garbage (i.e not reachable from any of the global roots). These objects are\r
+    marked as such, but not yet collected.\r
+  <LI>\r
+    The finalizer runs through all the previously marked objects and\r
+    <I>finalize</I> them by invoking their <CODE>finalize</CODE> method.\r
+</OL>\r
+<P>\r
+Until an object has been finalized, its memory cannot be reused. Both stages\r
+one and two can run either asynchronously (i.e. when the system is idle)\r
+or synchronously (i.e. because they are required to run in order for the\r
+process to continue its job). The problem we are experiencing in benches\r
+4.a and 4.b is the following: as the server is never idle during the bench,\r
+the asynchronous version of the two stages is never able to run, so &nbsp;the\r
+server relies entirely on the synchronous version of them. What really happens\r
+here is best depicted by running the server with the <I>verbosegc</I> option\r
+turned on:\r
+<PRE>www24:Jigsaw$ java -verbosegc w3c.jigsaw.http.httpd \r
+loading properties from: /afs/w3.org/usr/abaird/Jigsaw/config/httpd.props\r
+*** Warning : no logger specified, not logging.\r
+[httpd]: listening at:http://www24.w3.org:9999\r
+&lt;GC(async): freed 972 objects, 29712 bytes in 34 msec, 95% free&gt;\r
+&lt;GC(async): freed 2 objects, 16 bytes in 29 msec, 95% free&gt;\r
+&lt;GC: freed 3877 objects, 288960 bytes in 26 msec, 34% free&gt;\r
+&lt;GC: freed 736 objects, 285608 bytes in 23 msec, 54% free&gt;\r
+&lt;GC: freed 933 objects, 76040 bytes in 65 msec, 38% free&gt;\r
+&lt;GC: freed 1926 objects, 150320 bytes in 27 msec, 24% free&gt;\r
+&lt;GC: synchronously running 408 finalizers&gt;\r
+&lt;GC: freed 0 objects, 0 bytes in 64 msec, 24% free&gt;\r
+&lt;GC: expanded object space by 8192 to 847048 bytes, 25% free&gt;\r
+...[more traces omited]\r
+</PRE>\r
+<P>\r
+What happens here is that the asynchornous GC never gets a chance to run\r
+(as expected). The synchronous GC tells us about its good work, however free\r
+memory ratio never improves: the finalization process doesn't run. As for\r
+the GC we don't expect the asynchronous version of it to run, but the synchronous\r
+finalizer falsly indicate that it has finazlied some objects (while in fact,\r
+the synchronous finalizer was probably unable to finalize them, because the\r
+asynchronous finalizer was lying around).\r
+<P>\r
+For real fun, here are two other traces collected under <I>exactly</I> the\r
+same circumstances:\r
+<PRE>www24:Jigsaw$ java -verbosegc w3c.jigsaw.http.httpd \r
+loading properties from: /afs/w3.org/usr/abaird/Jigsaw/config/httpd.props\r
+*** Warning : no logger specified, not logging.\r
+[httpd]: listening at:http://www24.w3.org:9999\r
+&lt;GC(async): freed 972 objects, 29712 bytes in 34 msec, 95% free&gt;\r
+&lt;GC(async): freed 2 objects, 16 bytes in 27 msec, 95% free&gt;\r
+&lt;GC(async): freed 1424 objects, 92224 bytes in 61 msec, 86% free&gt;\r
+&lt;GC(async): freed 179 objects, 2368 bytes in 35 msec, 86% free&gt;\r
+&lt;GC(async): freed 520 objects, 41088 bytes in 33 msec, 86% free&gt;\r
+&lt;GC(async): freed 72 objects, 960 bytes in 38 msec, 86% free&gt;\r
+&lt;GC(async): freed 325 objects, 25680 bytes in 40 msec, 86% free&gt;\r
+&lt;GC(async): freed 45 objects, 600 bytes in 31 msec, 86% free&gt;\r
+&lt;GC(async): freed 1430 objects, 112992 bytes in 37 msec, 86% free&gt;\r
+&lt;GC(async): freed 198 objects, 2640 bytes in 31 msec, 86% free&gt;\r
+&lt;GC(async): freed 1950 objects, 154080 bytes in 37 msec, 86% free&gt;\r
+&lt;GC(async): freed 270 objects, 3600 bytes in 32 msec, 86% free&gt;\r
+</PRE>\r
+<P>\r
+This run is pretty ideal. For some reasons, the asynchronous GC manages to\r
+run, and the memory is taken care of nicely (<B>Jigsaw</B> achieved 30\r
+requests/second during this test).\r
+<P>\r
+The last configuration I have encountered is the following:\r
+<PRE>www24:Jigsaw$ java -verbosegc w3c.jigsaw.http.httpd \r
+loading properties from: /afs/w3.org/usr/abaird/Jigsaw/config/httpd.props\r
+*** Warning : no logger specified, not logging.\r
+[httpd]: listening at:http://www24.w3.org:9999\r
+&lt;GC(async): freed 972 objects, 29712 bytes in 35 msec, 95% free&gt;\r
+&lt;GC(async): freed 2 objects, 16 bytes in 27 msec, 95% free&gt;\r
+&lt;GC: freed 9208 objects, 707008 bytes in 33 msec, 84% free&gt;\r
+&lt;GC: freed 7233 objects, 571648 bytes in 34 msec, 82% free&gt;\r
+&lt;GC: freed 5834 objects, 460704 bytes in 34 msec, 81% free&gt;\r
+&lt;GC: freed 4550 objects, 359520 bytes in 34 msec, 80% free&gt;\r
+&lt;GC: freed 4485 objects, 354384 bytes in 36 msec, 79% free&gt;\r
+&lt;GC: freed 4420 objects, 349248 bytes in 41 msec, 78% free&gt;\r
+&lt;GC: freed 4355 objects, 344112 bytes in 40 msec, 77% free&gt;\r
+&lt;GC: freed 4355 objects, 344112 bytes in 42 msec, 76% free&gt;\r
+&lt;GC: freed 4355 objects, 344112 bytes in 44 msec, 75% free&gt;\r
+&lt;GC: freed 4290 objects, 338976 bytes in 45 msec, 74% free&gt;\r
+&lt;GC: freed 4160 objects, 328704 bytes in 46 msec, 73% free&gt;\r
+&lt;GC: freed 7222 objects, 309792 bytes in 41 msec, 79% free&gt;\r
+&lt;GC: freed 6319 objects, 297248 bytes in 31 msec, 83% free&gt;\r
+&lt;GC: freed 8631 objects, 647424 bytes in 32 msec, 84% free&gt;\r
+&lt;GC(async): freed 2557 objects, 129320 bytes in 42 msec, 86% free&gt;\r
+&lt;GC(async): freed 212 objects, 2848 bytes in 32 msec, 86% free&gt;\r
+</PRE>\r
+<P>\r
+The memory keeps getting down, slowly. If the test continues for a while,\r
+the interpreter will fall back in the first situation presented above (i.e.\r
+trashing). However, whenever the test is stopped (as in the last two lines\r
+above) the asynchronous GC normally runs and get back all the memory.\r
+<H2>\r
+  Conclusion\r
+</H2>\r
+<P>\r
+What can you expect - with regard to performances - in the next <B>Jigsaw</B>\r
+release ? As said above, the <B>Jigsaw</B> implementation should improve,\r
+and provide better performances.\r
+<P>\r
+However, some real speed-up can be expected by better Java implementations\r
+in the next six monthes. By this time, the GC will hopefully be debugged,\r
+and on solaris at least, we can expect the native solaris threads to replace\r
+the Green thread package that is currently being used.\r
+<P>\r
+Send suggestions, comments, criticisms, corrections to\r
+<A HREF="mailto:jigsaw@w3.org">Jigsaw Team</A>\r
+<P>\r
+  <HR>\r
+<BR>\r
+<A HREF="mailto:jigsaw@w3.org">Jigsaw Team</A>.<BR>\r
+$Id: performance.html,v 1.1 2010/06/15 12:20:09 smhuang Exp $\r
+</BODY></HTML>\r