2010-01-26 4 views
2

J'ai un problème avec une fuite de mémoire Java, qui pour une raison quelconque n'apparaît pas dans mon profileur (Yourkit). Quand j'exécute mon application Java (un serveur avec des threads pour écouter, envoyer et traiter des données) il semble que chaque fois que je reçois une nouvelle connexion et que cette connexion est supprimée, la mémoire n'est pas nettoyée. Au moins, c'est ce que Windows (et Linux) disent. Lorsque j'exécute mon application avec mon profileur, il affiche simplement la mémoire comme elle est censée être, quand un thread est fermé, toute la mémoire est nettoyée. Cependant, en réalité, après un certain temps Java s'est simplement écrasé parce qu'il utilise trop de mémoire, donc indépendamment de ce que dit mon profileur, j'ai tendance à croire que Windows et Linux l'utilisent. L'exécution de garbage collection ne nettoie pas non plus la mémoire.Comment trouver une fuite de mémoire java

Alors qu'est-ce que cela pourrait être? J'ai essayé tout ce que je sais, ferme les threads, mets tous les objets à zéro, supprime le contenu de chaque tableau, etc. Je suis sûr que les threads sont fermés car Eclipse et le compilateur et les impressions semblent le confirmer.

Est-ce que quelqu'un a une idée?

+2

Comment savez-vous que trop d'utilisation de la mémoire est le problème? Obtenez-vous 'OutOfMemoryError'? – danben

+0

Voir aussi: http: // stackoverflow.com/questions/1473510/general-strategy-to-resolution-java-memory-leak (Le premier hit dans le panneau des questions connexes ... vous avez vérifié les questions connexes, n'est-ce pas?) – meriton

+0

Suite au commentaire de danben: vous pouvez obtenir Les erreurs "Out Of Memory" qui signifient en fait que vous avez dépassé une limite sur le nombre de threads en cours d'utilisation. Peut-être que c'est ce qui se passe et c'est pourquoi votre profileur ne montre pas que vous n'avez plus de mémoire. Si vous parlez de "définir des objets sur null", cela signifie que vous ne maîtrisez pas bien les concepts de base. Vous avez donc peut-être beaucoup de threads qui ne s'arrêtent pas. –

Répondre

0

Il semble que vous fassiez du profilage quelque chose dans le mauvais sens, vous pourriez manquer quelque chose.

Il est rare pour un profiler de manquer une fuite, et une qui est clairement assez mauvaise pour planter votre serveur. Avez-vous vérifié que la raison pour laquelle vous vous écrasez est liée à la mémoire? Pouvez-vous signaler la partie suspectée de votre code et quelques résultats de profilage?

0

Vous pouvez essayer de parcourir le tas - utilisez jmap pour créer un vidage de tas binaire, ce qui lancera un petit serveur local qui vous permettra de parcourir le contenu du tas. Eclipse a également un plugin graphique pour vous permettre de parcourir les tas.

jmap -dump:format=b,file=FILENAME PID 
jhat HEAPFILENAME 

Cela peut ne pas être très utile, mais c'est un début, par exemple. Si vous avez d'énormes cartes de chaînes, un tas de centaines de milliers de chaînes ne vous dit pas quelles cartes et quelles parties du code sont les contrevenants. Si vous créez beaucoup de threads, vous pouvez également essayer jstack, qui vous indiquera l'état des threads de tous les threads en cours d'exécution dans votre jvm.

2

Vous pouvez demander à votre machine virtuelle de générer un vidage de tas lors d'une erreur OutOfMemory, puis d'analyser ce tas.

Pour la machine virtuelle HotSpot de Sun, vous pouvez demander la génération de vidage de tas comme décrit here.

Pour analyser la sauvegarde, vous pouvez utiliser jVisualVM ou jhat. (Il peut y avoir de meilleurs outils, mais je n'en ai pas eu besoin jusqu'ici.)

0

Il existe une autre réponse, qui n'implique pas de fuite de mémoire, qui peut entraîner le crash d'un processus java. Stack Overflow. Est-ce que l'un de vos threads fait une récursivité? Est-ce que votre code crée une énorme pile d'appels? Vous devez poster le message d'erreur afin que nous puissions éliminer diverses possibilités.

1

Connectez-vous avec jvisualvm (dans Java 6 JDK) et vérifiez s'il fournit des informations (y compris le profilage) que YourKit ne contient pas.