views:

3391

answers:

6

Tomcat.exe is consuming 75% of CPU. Is anyone having any idea why it happens and how can that be decreased?

I am using Tomcat5.5 & J2SDK v 1.4.2_12

A: 

This is most likely caused by the application(s) that you are running on top of the tomcat. Of course if you have very high traffic on your applications, this could also be the reason.

Juha Syrjälä
+1  A: 

To understand what's happening, you should try to run it under a profiler. Try the YourKit (http://www.yourkit.com/) or Netbeans (http://profiler.netbeans.org/docs/help/5.5/profile_j2ee_profileproject.html).

The YourKit one have better integration with tomcat.

J-16 SDiZ
+1  A: 

If you're using 75% CPU and dont understand why, I suggest you issue a kill -3 to the tomcat process (ctrl-break if you have a console) to get a thread dump (when the load is high!). In my experience most threads should either be idle or in io-wait. Look for any single branch of code that has repeated occurences in the stack traces and that's your likely culprit (non-io waits!). This is the "poor man's profiler" that is quite often the best and most efficient way to solve these problems.

krosenvold
A: 

All the answers cover how to do an exact diagnose, in addition I would add that, from my experience, a infinite loop in one of your applications is probably the culprit.

As J-16 SDiZ said, your best bet is to run the profiler to narrow down the problem to one application.

James McMahon
A: 

Lambda Probe is a very handy tool for monitoring Tomcat.

Are you using a quad CPU system? Probably Tomcat is running 100% in 3 of them. I would first test for an infinite loop or something like that in an application.

kgiannakakis
A: 

First of all (this applies to all java applications) you must pin down which thread is using CPU. This is possible in JDK 1.6. It is done by using java.lang.management.ManagementFactory.getThreadMXBean(). Here is example usage (JSP):

<%@ page import="java.lang.management.*, java.util.*" %>
<%!
    Map cpuTimes = new HashMap();
    Map cpuTimeFetch = new HashMap();
%><%
long cpus = Runtime.getRuntime().availableProcessors();
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
long now = System.currentTimeMillis();
ThreadInfo[] t = threads.dumpAllThreads(false, false);
for (int i = 0; i < t.length; i++) {
    long id = t[i].getThreadId();
    Long idid = new Long(id);
    long current = 0;
    if (cpuTimes.get(idid) != null) {
        long prev = ((Long) cpuTimes.get(idid)).longValue();
        current = threads.getThreadCpuTime(t[i].getThreadId());
        long catchTime = ((Long) cpuTimeFetch.get(idid)).longValue();
        double percent = (current - prev) / ((now - catchTime) * cpus * 10000);
        if (percent > 0 && prev > 0) {
            out.println("<li>" + t[i].getThreadName() + " " + percent + " (" + prev + ", " + current + ")");    
        }
    }
    cpuTimes.put(idid, new Long(current));  
    cpuTimeFetch.put(idid, new Long(now));
}
%>

After that you can get a thread dump and analyze the code in this thread to fix excessive CPU usage.

huksley