10
votes

L'utilisation de la mémoire Java augmente lorsque l'application est utilisée, mais ne diminue pas lorsqu'elle n'est pas utilisée

J'ai une application Java qui utilise beaucoup de mémoire lorsqu'elle est utilisée, mais lorsque le programme n'est pas utilisé, l'utilisation de la mémoire ne diminue pas.

Y a-t-il un moyen de forcer Java à libérer cette mémoire? Parce que cette mémoire n'est pas nécessaire à ce moment-là, je peux comprendre de réserver une petite quantité de mémoire, mais Java se réserve juste toute la mémoire qu'elle utilise jamais. Il réduit également cette mémoire plus tard, mais il doit y avoir un moyen de forcer Java à le libérer lorsque ce n'est pas nécessaire.

système.gc ne fonctionne pas.


2 commentaires

System.GC suggère uniquement à la collecte de poubelles ... Cela ne forcait pas réellement une collection de déchets.


Vérifiez «Free -M», probablement beaucoup d'entre eux sont la cache, votre tas qui monte et fait avec GC normalement.


5 Réponses :


7
votes

Comme indiqué dans les commentaires, ce n'est pas certain que, tandis que le collecteur des ordures dispose des objets, il redonne la mémoire au système.

Peut-être Tuning Collection de la collection de déchets fournit la solution à votre problème:

Par défaut, le JVM augmente ou rétrécit le tas sur chaque GC pour conserver le rapport de l'espace libre pour vivre des objets à chaque collection dans une plage spécifiée.

  • -xx: minheapfreeratio - Lorsque le pourcentage d'espace libre dans une génération tombe en dessous de cette valeur, la génération sera étendue pour répondre à ce pourcentage. La valeur par défaut est 40
  • -xx: maxheapfreeratio - Lorsque le pourcentage d'espace libre dans une génération a dépassé cette valeur, la génération diminuera pour répondre à cette valeur. La valeur par défaut est 70

    Sinon, si vous soupçonnez que vous fassiez des références, vous pouvez déterminer comment, quoi et où les objets sont divulgués consiste à surveiller le tas dans Jvisalvm (un outil groupé avec le SDK standard). Vous pouvez, via ce programme, effectuer un heap-décharge et obtenir un histogramme sur la consommation de mémoire d'objet:

    Entrez la description de l'image ici


1 commentaires

Excellent point. Je n'y pensais pas comme ça. Réponse mise à jour.



0
votes

system.gc n'a aucune garantie si elle devrait libérer n'importe quelle mémoire lors de son exécution. Voir Pourquoi est-ce une mauvaise pratique d'appeler system.gc ( )?

Essayez de modifier le XMX JVM ARG Down s'il est réglé sur une grande valeur et jetez un coup d'œil à JConsole pour voir ce qui se passe avec une utilisation de la mémoire et une activité GC. Normalement, vous verriez un motif dentaire de scie.

Vous pouvez également utiliser un profileur pour voir où la mémoire est utilisée et identifier toutes les fuites.


0 commentaires

0
votes

Une des deux choses se passe:

1) Votre application fuit des références. Êtes-vous sûr de ne pas être suspendu aux objets lorsque vous n'en aurez plus besoin? Si vous le faites, Java doit les maintenir en mémoire.

2) Java fonctionne juste bien. Vous n'obtenez aucun avantage de la mémoire que vous n'utilisez pas.


0 commentaires

2
votes

Quelle mémoire voulez-vous dire? S'il s'agit de RAM (par opposition à la quantité d'espace de tas d'occasion de Java VM lui-même), cela pourrait être normal. Il s'agit d'une opération relativement coûteuse d'allouer la mémoire donc une fois que les JVM ont obtenu certaines, il est assez réticent à le remettre, même s'il n'est pas nécessaire à l'époque.


0 commentaires

1
votes

Avez-vous envisagé d'utiliser un profileur de mémoire? Si vous n'avez pas accès à un, vous pouvez commencer par capturer un tas de jmap -histo et écrire un script pour chiffrer les différences.


0 commentaires