2009-06-24 10 views
2

Ich habe eine Java-Web-Anwendung, die viel mit Dateikonventionen funktioniert.
Ich verwende Tomcat 6 als meinen Servlet-Container. Wenn viele Anfragen eingehen, wird Tomcat sehr speicherhungrig. Ich frage mich, wie ich Kater feinabstimmen kann, um den Speicherverbrauch zu reduzieren. Ich überlege auch, meinen Servlet-Container zu ändern.
Was schlagen Sie vor?Tuning Tomcat Speicher und CPU-Verbrauch

+0

Was meinst du mit "viel mit Datei Konventionen arbeiten"? –

Antwort

4

Sie können die akzeptierten/operativen Verbindungsnummern in der conf/server.xml Konfiguration begrenzen.

Haben

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" 
    maxThreads="16" minSpareThreads="1"/> 

und

<Connector executor="tomcatThreadPool" 
      port="8080" protocol="HTTP/1.1" 
      connectionTimeout="20000" 
      redirectPort="8443" 
      /> 

oder

<Connector port="8080" protocol="HTTP/1.1" 
      connectionTimeout="20000" 
      redirectPort="8443" 
      maxThreads='16'/> 

in der Konfigurationsdatei und diese sollten Sie bremsen.

Edit: auf Ihrem Kommentar Basierend Sie die Verarbeitung in gewidmet Thread-Pool Größe entsprechend Ihrer CPU-Anzahl bewegen konnte (Runtime.getRuntime().availableProcessors()) (siehe ExecutorService und Executors.) Dann Sie eine begrenzte LinkedBlockingQueue anwenden könnte die Zahl der anhängigen zu drosseln Aufgaben (vergessen Sie nicht, eine RejectedExecutionHandler angeben, um die Blockierung hinzuzufügen, wenn die Warteschlange voll wird).

Bearbeiten 2: Links zu den Klassen hinzugefügt. Dort finden Sie einige Beispiele.

Bearbeiten 3: Eine Beispielmethode, die ich in einem Projekt verwendet habe.

/** 
* Creates a new thread pool based on some attributes 
* @param poolSize the number of worker threads in the thread pool 
* @param poolName the name of the thread pool (for debugging purposes) 
* @param priority the base priority of the worker threads 
* @param capacity the size of the task queue used 
* @return the ExecutorService object 
*/ 
private ExecutorService newPool(int poolSize, 
String poolName, final int priority, int capacity) { 
    int cpu = Runtime.getRuntime().availableProcessors(); 
    ExecutorService result = null; 
    if (poolSize != 0) { 
     if (poolSize == -1) { 
      poolSize = cpu; 
     } 
     if (capacity <= 0) { 
      capacity = Integer.MAX_VALUE; 
     } 
     result = new ThreadPoolExecutor(poolSize, poolSize, 
       120, TimeUnit.MINUTES, 
       new LinkedBlockingQueue<Runnable>(capacity), 
     new ThreadFactory() { 
      @Override 
      public Thread newThread(Runnable runnable) { 
       Thread t = new Thread(runnable); 
       t.setPriority(priority); 
       return t; 
      } 
     }, new RejectedExecutionHandler() { 
      @Override 
      public void rejectedExecution(Runnable r, 
        ThreadPoolExecutor executor) { 
       if (!executor.isShutdown()) { 
        try { 
         executor.getQueue().put(r); 
        } catch (InterruptedException ex) { 
         // give up 
        } 
       } 
      } 
     }); 
    } 
    return result; 
} 

Und man konnte es auf diese Weise verwenden:

ExecutorService exec = newPool(-1, "converter pool", Thread.NORM_PRIORITY, 500); 
servletContext.setAttribute("converter pool", exec); 

Und in Ihrem Servlet

ExecutorService exec = (ExecutorService)servletContext 
.getAttribute("converter pool"); 

exec.submit(new Runnable() { 
    public void run() { 
     // your code for transformation goes here 
    } 
}