2009-06-24 5 views
2

J'ai une application Web Java qui fonctionne beaucoup avec les conventions de fichiers.
J'utilise Tomcat 6 comme conteneur de servlet. Lorsque de nombreuses requêtes sont soumises, Tomcat devient très gourmand en mémoire. Je me demande comment je peux affiner tomcat pour réduire la consommation de mémoire. Je considère aussi changer mon conteneur de servlets.
Que suggérez-vous?Optimisation de la mémoire et de la consommation du processeur Tomcat

+0

Que voulez-vous dire par "travailler beaucoup avec les conventions de fichiers"? –

Répondre

4

Vous pouvez limiter les numéros de connexion acceptés/opérationnels dans la configuration conf/server.xml.

Avez-

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

et

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

ou

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

dans le fichier de configuration et cela devrait vous frein.

Edit: Sur la base de votre commentaire, vous pouvez déplacer le traitement dans la piscine de fil dédié de taille en fonction de votre nombre de CPU (Runtime.getRuntime().availableProcessors()) (voir ExecutorService et Executors.) Vous pouvez ensuite appliquer une LinkedBlockingQueue limitée à étrangler le nombre d'attente tâches (n'oubliez pas de spécifier un RejectedExecutionHandler pour faire l'ajout de blocage lorsque la file d'attente est pleine).

Édition 2: Ajout de liens vers les classes. Là vous trouvez quelques échantillons.

Édition 3: Un exemple de méthode que j'ai utilisé dans un projet.

/** 
* 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; 
} 

Et vous pouvez l'utiliser de cette façon:

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

Et dans votre servlet

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

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