web-dev-qa-db-fra.com

Comment diagnostiquer une Java 8?

J'ai une application J2EE avec un comportement intéressant ... le tas semble bien se comporter, grandissant et rétrécissant avec les récupérations comme prévu au fil du temps. Il n'y a pas d'expansion globale appréciable du tas à long terme. Cependant, la métaspace continue de croître régulièrement à environ 20 Mo par heure jusqu'à ce que nous atteignions MaxMetaspace et rencontrions un OOME. J'ai essayé les collecteurs de déchets parallèles et G1 (jdk1.8.0_40).

L'application ne se redéploie pas pendant l'exécution, il ne semble donc pas que ce soit la fuite typique du chargeur de classe. Quelqu'un a-t-il des suggestions sur la façon de localiser la source de cette fuite?

34

Faites un vidage de tas et analysez-le avec Eclipse MAT . Regardez les classes que vous avez chargées. Vérifiez s'il y a quelque chose d'inattendu, en particulier des classes en double. Il a également un explorateur de chargeur de classe.

Edit: En théorie, vous pourriez également être que vous générez constamment des proxys.

7
Philippe Marschall

La cause principale de Java.lang.OutOfMemoryError: Metaspace est:

  • trop de classes ou
  • classes trop grandes chargées dans le Metaspace.

Si vous souhaitez recréer le problème, utilisez cet extrait de code:

public class Metaspace {
static javassist.ClassPool cp = javassist.ClassPool.getDefault();

public static void main(String[] args) throws Exception {
    for (int i = 0; ; i++) { 
        Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass();
    }
  }
}

Toutes ces définitions de classe générées finissent par consommer Metaspace.

Javaassist dans Repo Maven .

Vous pouvez trouver beaucoup plus sur OOME ici

5
Karol Król