Bonjour,

j'ai codé un petit serveur de jeu en Java. Tout fonctionne à merveille mais si je laisse tourner le serveur plus d'une semaine, je finis par me retrouver avec une OutOfMemory Exception. Je dois donc avoir une jolie petite fuite mémoire quelque part et une revue de mon code ne m'a pas permis d'en trouver l'origine.

Du coup, je me suis penché sur le moyen de générer des heapDumps de mon appli java en cours d'exécution (en prod). J'aimerais en effet pouvoir récupérer des infos concernant le nombre d'instances de chaque classe présentes dans la JVM à différents moments (et donc voir celles qui s'accumulent sans être libérées).

Après quelques recherches, je suis tombé sur l'article "How to obtain an IBM JVM heapdump" sur lequel je me suis basé pour me faire un petit script pour lancer mon serveur sous linux:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
clear
export IBM_HEAP_DUMP=true
export IBM_HEAPDUMP=true
export IBM_HEAPDUMPDIR=/home/mylogin/myServer/
export JAVA_DUMP_OPTS=ONANYSIGNAL\(ALL\)
 
java -cp myServer.jar myPackage.MyServerClass
Je récupère ensuite le PID de ma JVM avec un
et j'envoie le signal QUIT à la JVM pour lui demander de générer ledit heapDump:
Sur la sortie standard de mon serveur, j'obtiens alors une sorte de résumé qui me renseigne surtout sur les threads en cours d'exécution (cf ci-dessous).


Mais:

1/ Rien en ce qui concerne l'utilisation détaillée de la mémoire (quelles types d'objets, nombre d'instances) hormis un chiffre global

2/ Aucun fichier n'est généré à l'issue de cet appel alors que l'article en lien dit qu'on est censé générer un fichier de type PHD qu'on peut ensuite exploiter avec un programme tiers.

Si vous avez une idée, je suis preneur...
Merci d'avance


Full thread dump Java HotSpot(TM) Client VM (11.2-b01 mixed mode, sharing):

"DestroyJavaVM" prio=10 tid=0xb4f3fc00 nid=0x66a2 waiting on condition [0x00000000..0xb76bc070]
java.lang.Thread.State: RUNNABLE

"Thread-3" prio=10 tid=0xb4f27000 nid=0x66bb waiting on condition [0xb4c42000..0xb4c42eb0]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at gameserver.db.MysqlConnexion.run(MysqlConnexion.java:117)
at java.lang.Thread.run(Thread.java:619)

"Thread-2" prio=10 tid=0xb4f27c00 nid=0x66b7 runnable [0xb4c93000..0xb4c93e30]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384)
- locked <0x8ba40078> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:453)
at java.net.ServerSocket.accept(ServerSocket.java:421)
at gameserver.webconnector.WebServerModule.run(WebServerModule.java:86)
at java.lang.Thread.run(Thread.java:619)

"Thread-0" prio=10 tid=0xb4f20c00 nid=0x66b6 runnable [0xb4ce4000..0xb4ce4db0]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384)
- locked <0x8ba40240> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:453)
at java.net.ServerSocket.accept(ServerSocket.java:421)
at network.MsgServerSocket.run(MsgServerSocket.java:73)

"TimerQueue" daemon prio=10 tid=0xb4f34000 nid=0x66b5 in Object.wait() [0xb4d35000..0xb4d36130]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x8ba403c8> (a javax.swing.TimerQueue)
at javax.swing.TimerQueue.run(TimerQueue.java:236)
- locked <0x8ba403c8> (a javax.swing.TimerQueue)
at java.lang.Thread.run(Thread.java:619)

"Low Memory Detector" daemon prio=10 tid=0x0808e400 nid=0x66a8 runnable [0x00000000..0x00000000]
java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=10 tid=0x0808c400 nid=0x66a7 waiting on condition [0x00000000..0xb519ca48]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x0808ac00 nid=0x66a6 waiting on condition [0x00000000..0x00000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x08082000 nid=0x66a5 in Object.wait() [0xb53ef000..0xb53efeb0]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x8be522e8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
- locked <0x8be522e8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x08080c00 nid=0x66a4 in Object.wait() [0xb5440000..0xb5440e30]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x8be52370> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x8be52370> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x0807f000 nid=0x66a3 runnable

"VM Periodic Task Thread" prio=10 tid=0x08091400 nid=0x66a9 waiting on condition

JNI global references: 1035

Heap
def new generation total 960K, used 567K [0x8b960000, 0x8ba60000, 0x8be40000)
eden space 896K, 56% used [0x8b960000, 0x8b9ddca8, 0x8ba40000)
from space 64K, 100% used [0x8ba40000, 0x8ba50000, 0x8ba50000)
to space 64K, 0% used [0x8ba50000, 0x8ba50000, 0x8ba60000)
tenured generation total 4096K, used 638K [0x8be40000, 0x8c240000, 0x8f960000)
the space 4096K, 15% used [0x8be40000, 0x8bedfb38, 0x8bedfc00, 0x8c240000)
compacting perm gen total 12288K, used 2158K [0x8f960000, 0x90560000, 0x93960000)
the space 12288K, 17% used [0x8f960000, 0x8fb7ba68, 0x8fb7bc00, 0x90560000)
ro space 8192K, 74% used [0x93960000, 0x93f580d8, 0x93f58200, 0x94160000)
rw space 12288K, 58% used [0x94160000, 0x94873618, 0x94873800, 0x94d60000)