J'ai bêtement pensé, comme le laissait présager le message, que mes applications étaient à l'étroit dans le (petit ?) giga de mémoire que je réservais à la JVM. Mais un passage à 2Go n'y a rien changé. J'ai alors soupçonné mes développements en considérant une fuite mémoire dans une de mes applications. À force d'essais erreurs, je me suis rendu compte que le problème survenait non pas lors de l'utilisation de mes applications mais lors de l'utilisation de JIRA.

Les gens d'Atlassian sont plutôt d'excellents ingénieurs, j'ai eu un peu de mal à considérer qu'ils avaient laisser une bête fuite mémoire dans leur programme vedette ! Par contre, il est vrai que JIRA est une application bien plus complexe et lourde que toutes les autres applications qui tournent sur ce serveur.

L'analyse du problème m'a permis d'en découvrir un peu plus sur le fonctionnement de la JVM. La JVM utilise trois tas différents (heap en anglais) :

  • Un tas dit de jeune génération qui stocke les objets créés et aussitôt détruits par le garbage collector,
  • Le tas d'ancienne génération stocke les objets qui persistent en mémoire,
  • Enfin, le tas de génération permanente (permgen) qui stocke les définitions des classes, des méthodes et les métainformations associées.

Mon souci s'explique par le fait que :

  1. JIRA utilise un très grand nombre de classes et nécessite par conséquent beaucoup d'espace dans le permgen,
  2. L'espace mémoire du permgen est confiné et n'exploite pas l'espace alloué aux autres tas avec les options -Xmx et -Xms.

Cette configuration a donc provoqué dans mon système un débordement mémoire du tas quand bien même l'espace mémoire alloué à la JVM était sous utilisé. Le sens du message PermGen space prend alors tout son sens :)

Au final la solution est assez simple, il suffit d'augmenter l'espace mémoire alloué au permgen avec l'option dédiée -XX:MaxPermSize, soit dans mon cas : -XX:MaxPermSize=256m !