2009-04-03 6 views
4

Nous exécutons une application assez complexe en tant que portlet sur Websphere Portal Server 5.1 sous AIX à l'aide d'IBM JDK 1.4.2. Sur notre système de production, je peux voir un comportement étrange dans les journaux verbeux du GC. Après une période de comportement normal, le système peut commencer à allouer rapidement des blocs de plus en plus grands. Le système commence à passer plus de 1000 ms pour terminer chaque GC, mais les blocs sont alloués si rapidement qu'il n'y a qu'un écart de 30 ms entre les échecs d'allocation. Chaque échec d'allocation est légèrement plus grand que le dernier d'une certaine quantité x 1024 octets. Par exemple. vous pourriez avoir 5 Mo, puis un peu plus tard 5 Mo + 17 * 1024. Comportement étrange de récupération de place avec Websphere Portal Server

  • Cela peut durer jusqu'à 10 minutes.
  • Les blocs ont tendance à grossir jusqu'à 8 à 14 Mo avant de s'arrêter.
  • C'est un système à quatre cœurs, et je suppose qu'il passe maintenant> 95% de son temps à faire du GC avec trois cœurs en attente de l'achèvement de l'autre GC. Pendant 10 minutes. Aie.
  • Évidemment, les performances du système meurent à ce stade.
  • Nous avons JSF, hibernate & JDBC, les appels de services Web, la sortie log4j et pas grand chose d'autre. J'interprète ceci comme étant probablement quelque chose d'infrastructure plutôt que notre code d'application. S'il s'agissait d'une mauvaise concaténation de chaînes à l'intérieur d'une boucle, nous nous attendrions à une croissance plus irrégulière que les blocs de 1024. Si c'était la croissance de StringBuffer ou de ArrayList, nous verrions les tailles de blocs doubler. La croissance me fait penser à la mise en mémoire tampon des journaux ou à autre chose. Je ne peux pas penser à quoi que ce soit dans notre application que les allocations même 1 Mo, encore moins 14. Aujourd'hui, je cherchais la sauvegarde de sauvegarde en mémoire avant d'être vidé sur le disque, mais le volume des déclarations de journalisation sur cette période de GC était nulle part la gamme MB. Il est clair que le problème est dû à l'allocation excessive de mémoire plutôt qu'à la récupération de place, qui fait de son mieux pour suivre le rythme. Quelque chose alloue un gros bloc et essaie de le développer de manière inefficace par incréments qui sont beaucoup trop petits.

    Des idées sur ce qui pourrait être à l'origine de tout cela lorsque le système est sous charge? Quelqu'un at-il vu quelque chose de similaire avec Portal Server?

    Note: pour ceux qui sont intéressés, il semble que la cause soit une requête de base de données occasionnelle mais énorme. Il semble que le coupable soit Hibernate ou le pilote JDBC.

  • Répondre

    1

    Selon la version exacte d'IBM JDK que vous utilisez, il existe différentes options pour le suivi des "allocations importantes". Les différences sont principalement dans la mise en œuvre, et le résultat est une trace de la pile Java de journalisation lorsqu'une allocation sur une certaine taille est faite (ce qui devrait vous aider à traquer le coupable).

    "souverain" SR4 + 1.4.2: http://www-01.ibm.com/support/docview.wss?uid=swg21236523

    "J9" 1.4.2 (si Java est en cours d'exécution sous option -Xj9): Vous devez saisir un agent JVMPI/JVMTI pour la même but, je ne peux pas trouver un lien pour celui-ci en ce moment.

    +0

    Notez que dans les versions récentes d'IBM Java 5 & 6, il existe désormais un agent de vidage que vous pouvez utiliser. L'option est -Xdump: stack: events = allocation, filter = # . peut être une taille droite comme "5m" ou une plage comme "256k..512k". N'oublie pas le "#" avant même! Consultez le Guide de diagnostic Java pour plus d'informations. –

    2

    Vous ne savez pas ce qui pourrait causer le problème, mais voici une idée sur la façon d'enquêter plus: IBM JDK est génial car il peut être configuré pour faire un vidage de tas lorsqu'il reçoit un signal SIGQUIT.
    Dans un projet précédent, ce n'était pas notre JDK, mais nous l'utilisions chaque fois que nous avions des problèmes de mémoire à étudier.

    Voici comment activer la heapdump: http://publib.boulder.ibm.com/infocenter/javasdk/v1r4m2/index.jsp?topic=/com.ibm.java.doc.diagnostics.142j9/html/enabling_a_heapdump.html

    Ensuite, il y a un outil appelé heaproot qui vous permettra de voir ce qui est dans ces décharges. Trouver le type d'objets devrait vous mener au coupable.

    +0

    Si vous rassemblez un tas, alors vous pourriez faire pire que d'utiliser http://eclipse.org/mat pour analyser le fichier. Si vous installez le plugin IBM DTFJ heapdump reader, vous disposez d'une interface très agréable pour parcourir les gros objets de votre tas. –

    0

    Juste un indice ... une fois que nous avions un projet qui a souffert de problèmes GC majeurs (Websphere et IBM JDK) en raison de la fragmentation de tas. À la fin, nous avons ajouté un commutateur JDK pour forcer le compactage du tas.

    Le JDK Sun ne tente pas d'avoir un tas fragmenté, mais IBM JDK le fait en raison de la gestion différente de la mémoire/GC. Faites un essai ... Je ne me souviens plus du commutateur magique.

    +0

    http://www.ibm.com/developerworks/ibm/library/i-incrcomp/ – trunkc