2010-09-23 4 views
3

J'utilise Eclipse 3.6 avec la dernière version de Sun Java 6 sous Linux (64 bits) avec un plus grand nombre de grands projets. Dans certaines circonstances particulières (mises à jour SVN par exemple), Eclipse nécessite jusqu'à 1 Go de tas. Mais la plupart du temps, il n'a besoin que de 350 Mo. Lorsque j'activer le panneau d'état du tas alors je vois la plupart du temps:Récupération d'Eclipse sur le système

350m 878m

Je commence Eclipse avec ces paramètres: -Xms128m -Xmx1024m

Donc la plupart des lots temps de MB sont juste gaspillés et sont rarement utilisés lorsque l'utilisation de la mémoire atteint son maximum pendant une courte période. Je n'aime pas ça du tout et je veux qu'Eclipse restitue la mémoire au système, donc je peux l'utiliser pour d'autres programmes.

Lorsque Eclipse a besoin de plus de mémoire alors qu'il n'y a pas assez de RAM libre que Linux peut échanger d'autres programmes en cours d'exécution, je peux vivre avec cela. J'ai entendu dire qu'il y a une option -XX: MaxHeapFreeRatio. Mais je n'ai jamais compris quelles valeurs je devais utiliser pour que ça fonctionne. Aucune valeur que j'ai essayé n'a jamais fait une différence. Alors, comment puis-je dire à Eclipse (ou Java) de libérer le tas inutilisé?

+0

Avez-vous essayé ce eclipse.ini (http://stackoverflow.com/questions/142357/what-are-the-best-jvm-settings-for-eclipse/3275659#3275659) avec vos paramètres Xms Xmx? – VonC

Répondre

11

Trouvé une solution. J'ai changé Java pour utiliser le garbage collector G1 et maintenant les paramètres HeapFreeRatio fonctionne comme prévu. Donc j'utiliser ces options eclipse.ini:

-XX:+UnlockExperimentalVMOptions 
-XX:+UseG1GC 
-XX:MinHeapFreeRatio=5 
-XX:MaxHeapFreeRatio=25 

Maintenant lorsqu'Eclipse mange plus de 1 Go de RAM pour une opération compliquée et rallumé à 300 Mo après Garbage Collection la mémoire est effectivement remis à l'exploitation système.

2

Vous pouvez accéder au Preferences -> General et vérifier le Show heap status. Ceci active une belle vue de votre tas dans le coin d'Eclipse. Quelque chose comme ceci:

alt text

Si vous cliquez sur la poubelle, il va essayer de lancer la collecte des ordures et retourner la mémoire.

+2

Je connais cet affichage d'état (même mentionné dans ma question) et je connais ce bouton poubelle mais il ne fait fonctionner que le garbage collector et ne restitue pas de mémoire au système. Donc, si Eclipse avait un pic d'utilisation de la mémoire courte de 1 Go, la taille du tas reste à 1 Go pour toujours (jusqu'à ce que je redémarre Eclipse), même lorsque seulement 300 Mo du tas sont réellement utilisés. – kayahr

1

Le tas de Java n'est rien de plus qu'une grosse structure de données gérée dans l'espace de tas du processus JVM. Les deux tas sont des entités logiquement séparées même si elles occupent la même mémoire.

La JVM est à la merci des implémentations du système hôte malloc(), qui attribue la mémoire du système en utilisant brk(). Sur les systèmes Linux (Solaris aussi), la mémoire allouée au tas de processus n'est presque jamais retournée, en grande partie parce qu'elle devient fragmentée et que le tas doit être contigu. Cela signifie que la mémoire allouée au processus augmentera de façon monotone, et que la seule façon de réduire la taille est de ne pas l'allouer en premier lieu. Indiquez à la machine virtuelle Java comment dimensionner le tas Java à l'avance, ce qui lui permet d'allouer de la mémoire de processus. Java peut ramasser les ordures jusqu'à ce que le soleil s'éteigne, mais ce nettoyage est interne à la JVM et la sauvegarde de la mémoire de processus n'est pas retournée.


Elaboration de commentaire ci-dessous:

La méthode standard pour un programme écrit en C (notamment la machine virtuelle Java en cours d'exécution Eclipse pour vous) pour allouer de la mémoire est d'appeler malloc(3), qui utilise le mécanisme prévu OS pour allouer de la mémoire au processus, puis gérer les allocations individuelles au sein de ces allocations. Les détails de fonctionnement de malloc() et free() sont spécifiques à l'implémentation.

Sur la plupart des versions d'Unix, un processus obtient exactement un segment de données, qui est une zone de mémoire contiguë avec des pointeurs au début et à la fin. Le processus peut ajuster la taille de ce segment en appelant brk(2) et en augmentant le pointeur de fin pour allouer plus de mémoire ou en le diminuant pour le renvoyer au système.Seulement la fin peut être ajustée. Cela signifie que si votre implémentation de malloc() agrandit le segment de données, l'implémentation correspondante de free() ne peut pas le réduire à moins qu'il ne détermine qu'il y a de l'espace à la fin qui n'est pas utilisé. En pratique, un gros morceau de mémoire que vous avez alloué avec malloc() finit rarement à la toute fin du segment de données lorsque vous le mettez à free(), ce qui explique pourquoi les processus ont tendance à croître de façon monotone.

+0

Est-ce que cela signifie qu'il s'agit d'un problème de système d'exploitation et que la mémoire est correctement renvoyée au système sous Windows? Existe-t-il des sources officielles indiquant que cela ne fonctionne pas sous Linux? – kayahr

+0

Ce n'est pas un problème de système d'exploitation. Dans votre cas, il s'agit de la quantité de mémoire de processus allouée par votre JVM pour le tas de Java, comment elle est libérée et comment la mémoire de processus est gérée par l'allocateur utilisé par la JVM (généralement 'malloc()' de la libc). J'en ai développé un peu plus dans ma réponse originale. Toute «déclaration officielle» sur le comportement d'une mise en œuvre particulière serait la source de cette mise en œuvre. – Blrfl

Questions connexes