Je cours un long lot sur mon application Grails. Le service contacte un service Web et télécharge le fichier XML qui est stocké localement dans l'application grails (dans la base de données). Les objets téléchargés sont assez volumineux et complexes et l'application les traite et crée des objets de domaine local. J'utilise Grails 1.2.2 parce que je ne pouvais pas mettre à jour mon application à la version la plus récente (j'ai passé quelques heures dessus et j'ai jeté l'éponge).OutOfMemoryError pendant un long batch sur Grails/Tomcat
C'est fondamentalement une longue boucle avec peu d'informations partagées entre les itérations.
Il est quelque chose comme:
while(stillObjectsToDo){
def bigObj = myservice.fetchXML
def localInstance = myservice.processObj(bigObj)
localInstance.saveEverythingToDB
clearGORM
}
je lance l'application sur Tomcat, qui a été peaufiné pour augmenter la taille du tas. Lorsque je traite un seul objet, je n'ai jamais eu de problème. Mais quand je lance le lot complet (environ 1500 grands objets), je reçois toujours:
codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionException: Executing action [runSampleBatch] of controller [semanticopenstreetmap.EngineController] caused exception: java.lang.OutOfMemoryError: Java heap space
at java.lang.Thread.run(Thread.java:619)
Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.OutOfMemoryError: Java heap space
... 1 more
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2882)
Il semble une sorte de fuite de mémoire, mais je ne peux pas le localiser. C'est vraiment étrange parce que les objets sont stockés dans la base de données et ne sont plus utilisés dans la procédure, donc ils devraient juste être rincés.
J'ai essayé les solutions suivantes pour éviter le problème avec pas de chance:
- Effacer Session Hibernate après le rinçage chaque objet à chaque itération
- Appel garbage collector toutes les 5-6 minutes.
- annule manuellement l'objet précédent à la fin du cycle (probablement inutile).
Rien de tout cela n'a fonctionné efficacement. L'utilisation de la mémoire ne cesse de croître. je Virtual VM et je suis arrivé ce graphique: http://img12.imageshack.us/img12/5660/memoryleak.png Et les classes: http://img263.imageshack.us/img263/331/memoryleakclasses.png
Comment puis-je localiser et résoudre cette fuite de mémoire?
EDIT: Cela aurait-il un sens d'exécuter chaque objet dans un fil séparé ? La fuite de mémoire se produit dans un processus http-0-x, comment puis-je inspecter cet objet?
Des indices?
Merci!
Mulone
quel collecteur grabage utilisez-vous? –
J'utilise celui par défaut: Runtime.getRuntime(). TotalMemory() et Runtime.getRuntime(). FreeMemory() – Mulone