Servlet “a commencé un fil, mais pas réussi à l'arrêter” fuite de mémoire dans Tomcat
Apache Tomcat dit de nombreuses fois:
L'application web [/MyServlet] semble avoir commencé un thread nommé [piscine-61-thread-2], mais n'a pas l'arrêter. Ce qui est très susceptible de créer une fuite de mémoire.
Est-ce dangereux? La servlet doit être capable de gérer 10.000 demandes/jour.
Comment fermer les fils quand ils ont fini?
class Worker {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
private final int threadNumber;
Worker(
CountDownLatch startSignal,
CountDownLatch doneSignal,
int threadNumber
){
this.startSignal = startSignal;
this.doneSignal = doneSignal;
this.threadNumber = threadNumber;
}
public String[][] getSomeStrArrArr() {
String[][] isRs = new String[8][20];
String[][] inRs = new String[8][20];
String[][] iwRs = new String[8][20];
try {
startSignal.await();
if (threadNumber == 1) {
//get String[][] result for thread number 1
isRs = getIS(erg1, erg2, request);
}
if (threadNumber == 2) {
//get String[][] result for thread number 2
inRs = getIN(search_plz, request);
}
if (threadNumber == 3) {
//get String[][] result for thread number 3
iwRs = getIW(erg1, erg2, request);
}
doneSignal.countDown();
} catch (InterruptedException ex) {
System.out.println(
"Thread number "+threadNumber+" has been interrupted."
);
}
if (threadNumber == 1) {
return isRs;
}
if (threadNumber == 2) {
return inRs;
}
if (threadNumber == 3) {
return iwRs;
}
return null;
}
public Callable<String[][]> getSomeCallableStrArrArr(){
return new Callable<String[][]>() {
public String[][] call() throws Exception {
return getSomeStrArrArr();
}
};
}
}
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<String[][]>> set = new HashSet<Future<String[][]>>();
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(3);
for (int i=1;i<=3;i++) {
Worker worker = new Worker(startSignal,doneSignal,i);
Callable<String[][]> callable =
worker.getSomeCallableStrArrArr();
Future<String[][]> future = pool.submit(callable);
set.add(future);
}
startSignal.countDown();
try {
doneSignal.await();
Habituellement, vous ne devriez pas initialiser de nouvelles discussions dans un environnement multithread, au lieu de laisser le serveur d'application poignée d'entre eux, sauf si vous savez ce que vous faites. Nous aurions besoin de plus d'informations pour obtenir une meilleure compréhension de votre problème, ou utiliser un profiler comme Eclipse de la Mémoire de l'Analyseur pour vérifier d'où la fuite de mémoire se trouve.
Nettoyer le reclassement est un très fragiles chose dans Tomcat (et pas seulement de Tomcat). Redémarrer le serveur est souvent inévitable, et puis les fuites ne sont pas un problème.
Sry, que voulez-vous dire par qui et comment l'éviter?
Nettoyer le reclassement est un très fragiles chose dans Tomcat (et pas seulement de Tomcat). Redémarrer le serveur est souvent inévitable, et puis les fuites ne sont pas un problème.
Sry, que voulez-vous dire par qui et comment l'éviter?
OriginalL'auteur user3876178 | 2014-08-04
Vous devez vous connecter pour publier un commentaire.
Oui, c'est un problème. Si votre code commence non-fils de démon, puis ceux des threads de continuer à travailler jusqu'à ce qu'ils sortent de leur méthode run. Même si tout le reste les finitions, le vieux de la JVM va traîner tandis que les discussions continuent sur. Si vous démarrez une nouvelle instance, alors vous pouvez avoir une situation où les vieux threads sont encore à travailler aux côtés de celles créées par la nouvelle instance.
Les tâches doivent être conçus de sorte qu'ils seront réceptifs à l'interruption (par opposition à la consommation de l'exception et de la passe, qui est ce que votre exemple montre). Cela signifie que la vérification de l'interruption du drapeau sur le thread en cours, et la capture d'InterruptedException d'une manière utile qui permet la tâche de briser son travail et réinitialise également l'interruption du pavillon en cas de besoin. ExecutorService implémentations ont shutdownNow méthode qui permet d'interrompre les tâches actuelles.
Voici un exemple de procédure d'arrêt d'un thread à l'aide de l'interruption.
Assurez-vous que l'exécuteur testamentaire est arrêté, vous pouvez gérer cela dans un ServletContextListener.
votre exemple est incomplet, êtes-vous rien faire pour arrêter votre piscine à l'heure actuelle?
ExecutorService.shutdownNow. il est utile que si les tâches de répondre à l'interruption.
simple mais ça marche! j'espère que je travaille mais je n'ai pas d'erreur plus. Merci! Savez-vous quelque chose à ce sujet: "L'application web [/MyServlet] semble avoir commencé un thread nommé [MySQL Déclaration d'Annulation de la Minuterie] mais n'a pas l'arrêter. Ce qui est très susceptible de créer une fuite de mémoire." Je viens d'avoir une certaine normale mysql appels, rien de spécial...
voir stackoverflow.com/q/15632153/217324
OriginalL'auteur Nathan Hughes