Featured Whitepapers
Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Tackle Java server capacity problems

Improve the capacity of your Java server application through load testing and analysis

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 3 of 6

The GrinderServlet

The GrinderServlet class, shown in Listing 1, and the Grinder class, shown in Listing 2, make up my test application.

Listing 1

 package pub.capart;

import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*;

public class GrindServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Grinderv1 grinder = Grinderv1.getGrinder(); long t1 = System.currentTimeMillis(); grinder.grindCPU(13); long t2 = System.currentTimeMillis();

PrintWriter pw = res.getWriter(); pw.print("<html>\n< body> \n"); pw.print("Grind Time = "+(t2-t1)); pw.print("< body> \n< /html> \n"); } }


Listing 2

 package pub.capart;

/** * This is a simple class designed to simulate an application consuming * CPU, memory, and contending for a synchronization lock. */ public class Grinderv1 { private static Grinderv1 singleton = new Grinderv1(); private static final String randstr = "this is just a random string that I'm going to add up many many times";

public static Grinderv1 getGrinder() { return singleton; } public synchronized void grindCPU(int level) { StringBuffer sb = new StringBuffer(); String s = randstr; for (int i=0;i<level;++i) { sb.append(s); s = getReverse(sb.toString()); } } public String getReverse(String s) { StringBuffer sb = new StringBuffer(s); sb = sb.reverse(); return sb.toString(); } }


These listings are brief, but interesting to study because they reproduce two common problems. The most glaring is probably the bottleneck caused by the synchronization modifier on the grindCPU() method, but the memory consumption will actually prove to be an even worse problem. The results of my first load test, displayed in Figure 1, show a modest load gently ramped up against version one of the GrinderServlet. Ramping up the load is important, because otherwise you are simulating a vastly larger initial load. It is also more accurate to "warm up" your application and avoid artifacts such as JSP (JavaServer Pages) compilation. I generally run a single simulated user through the application before beginning the load test.

Figure 1



I use the same capacity summary plot throughout this article. Much more information is available when performing a load test, but this provides a useful summary. The top panel contains throughput, the number of completed requests per second, and request-duration information from the load-testing software. Throughput most accurately quantifies capacity. The second panel contains the number of active users and a failure rate. I consider timeouts, bad server responses, and any requests taking more than five seconds to be failures. The third panel contains JVM memory statistics and CPU utilization. The CPU is an average of user time across all processors. All machines used in my load testing have two processors. The memory statistics contain a graph of garbage collections and the rate of garbage collections per second.

The two most obvious features from Figure 1 are the 50 percent CPU utilization—this test was run on a dual CPU machine—and the enormous amount of memory being consumed and immediately released. The reasons for both should be readily obvious after examining Listing 2. The synchronization modifier serializes all processing, restricting the number of CPUs to just one. The algorithm itself consumes enormous amounts of memory in local variables.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources