Existe-t-il un moyen de libérer de la mémoire en Java, similaire à la free()
fonction C ? Ou est-ce que définir l'objet sur null et s'appuyer sur GC est la seule option?
java
garbage-collection
Félix
la source
la source
Réponses:
Java utilise la mémoire gérée, donc la seule façon d'allouer de la mémoire est d'utiliser l'
new
opérateur, et la seule façon de désallouer de la mémoire est de s'appuyer sur le garbage collector.Ce livre blanc sur la gestion de la mémoire (PDF) peut vous aider à expliquer ce qui se passe.
Vous pouvez également appeler
System.gc()
pour suggérer que le garbage collector s'exécute immédiatement. Cependant, c'est le Java Runtime qui prend la décision finale, pas votre code.Selon la documentation Java ,
la source
System.gc()
totalement.Personne ne semble avoir mentionné explicitement la définition de références aux objets
null
, ce qui est une technique légitime pour «libérer» la mémoire que vous voudrez peut-être envisager.Par exemple, supposons que vous ayez déclaré un
List<String>
au début d'une méthode dont la taille a augmenté pour devenir très grande, mais qui n'a été nécessaire que jusqu'à la moitié de la méthode. Vous pouvez à ce stade définir la référence List surnull
pour permettre au garbage collector de récupérer potentiellement cet objet avant que la méthode ne se termine (et la référence tombe de toute façon hors de portée).Notez que j'utilise rarement cette technique en réalité, mais cela vaut la peine d'être pris en compte lorsque vous traitez de très grandes structures de données.
la source
Non recommandé.
Edit: J'ai écrit la réponse originale en 2009. Nous sommes maintenant en 2015.
Les éboueurs se sont régulièrement améliorés au cours des ~ 20 ans d'existence de Java. À ce stade, si vous appelez manuellement le garbage collector, vous pouvez envisager d'autres approches:
la source
* "Personnellement, je compte sur l'annulation des variables comme espace réservé pour une future suppression correcte. Par exemple, je prends le temps d'annuler tous les éléments d'un tableau avant de supprimer (rendre nul) le tableau lui-même."
Ceci est inutile. La façon dont le GC Java fonctionne est qu'il trouve des objets qui n'ont aucune référence à eux, donc si j'ai un Object x avec une référence (= variable) a qui pointe vers lui, le GC ne le supprimera pas, car il y a une référence à cet objet:
Si vous null a que cela se produit:
Alors maintenant, x n'a pas de référence pointant vers lui et sera supprimé. La même chose se produit lorsque vous définissez a pour faire référence à un objet différent de x.
Donc, si vous avez un tableau arr qui fait référence aux objets x, y et z et une variable a qui fait référence au tableau, cela ressemble à ça:
Si vous null a que cela se produit:
Ainsi, le GC trouve arr comme n'ayant aucune référence définie et le supprime, ce qui vous donne cette structure:
Maintenant, le GC trouve x, y et z et les supprime également. Annuler chaque référence dans le tableau ne fera rien de mieux, cela utilisera simplement du temps CPU et de l'espace dans le code (cela dit, cela ne fera pas mal plus que cela. Le GC sera toujours en mesure de fonctionner comme il le devrait. ).
la source
Une raison valable de vouloir libérer de la mémoire de n'importe quel programme (java ou non) est de rendre plus de mémoire disponible pour d'autres programmes au niveau du système d'exploitation. Si mon application java utilise 250 Mo, je peux le forcer à 1 Mo et rendre le 249 Mo disponible pour d'autres applications.
la source
Pour prolonger la réponse et le commentaire de Yiannis Xanthopoulos et Hot Licks (désolé, je ne peux pas encore commenter!), Vous pouvez définir les options de la VM comme cet exemple:
Dans mon jdk 7, cela libèrera alors la mémoire de la VM inutilisée si plus de 30% du tas devient libre après GC lorsque la VM est inactive. Vous devrez probablement régler ces paramètres.
Bien que je ne l'ai pas vu souligné dans le lien ci-dessous, notez que certains garbage collector peuvent ne pas obéir à ces paramètres et que par défaut, java peut en choisir un pour vous, si vous avez plus d'un cœur (d'où l'argument UseG1GC ci-dessus ).
Arguments de VM
Mise à jour: Pour java 1.8.0_73, j'ai vu la JVM publier occasionnellement de petites quantités avec les paramètres par défaut. Semble ne le faire que si ~ 70% du tas est inutilisé cependant ... je ne sais pas si la libération serait plus agressive si le système d'exploitation manquait de mémoire physique.
la source
J'ai fait des expériences à ce sujet.
Il est vrai que cela
System.gc();
suggère uniquement d'exécuter le garbage collector.Mais appeler
System.gc();
après avoir défini toutes les références ànull
, améliorera les performances et l'occupation de la mémoire.la source
Si vous voulez vraiment allouer et libérer un bloc de mémoire, vous pouvez le faire avec des ByteBuffers directs. Il existe même un moyen non portable de libérer de la mémoire.
Cependant, comme cela a été suggéré, ce n'est pas parce que vous devez libérer de la mémoire en C que vous devez le faire.
Si vous pensez que vous avez vraiment un bon cas d'utilisation gratuit (), veuillez l'inclure dans la question afin que nous puissions voir ce que vous voulez faire, il est fort probable qu'il existe un meilleur moyen.
la source
Entièrement à partir de javacoffeebreak.com/faq/faq0012.html
la source
Dans mon cas, étant donné que mon code Java est destiné à être porté dans d'autres langages dans un proche avenir (principalement C ++), je veux au moins payer du bout des lèvres pour libérer correctement la mémoire afin que cela facilite le processus de portage plus tard.
Je compte personnellement sur l'annulation des variables comme espace réservé pour une future suppression appropriée. Par exemple, je prends le temps d'annuler tous les éléments d'un tableau avant de supprimer (rendre nul) le tableau lui-même.
Mais mon cas est très particulier, et je sais que je prends des performances en faisant cela.
la source
* "Par exemple, supposons que vous ayez déclaré une liste au début d'une méthode dont la taille est devenue très grande, mais qui n'a été requise que jusqu'à la moitié de la méthode. Vous pouvez à ce stade définir la référence de liste sur null pour permettre au garbage collector de récupérer potentiellement cet objet avant que la méthode ne se termine (et que la référence tombe de toute façon hors de portée). " *
C'est correct, mais cette solution peut ne pas être généralisable. Lors de la définition d'une référence d'objet List sur null - rendra la mémoire disponible pour le garbage collection, cela n'est vrai que pour un objet List de types primitifs. Si l'objet List contient à la place des types de référence, la définition de l'objet List = null ne déréférencera aucun des types de référence contenus dans la liste. Dans ce cas, la définition de l'objet List = null rendra orphelins les types de référence contenus dont les objets ne seront pas disponibles pour le garbage collection à moins que l'algorithme de garbage collection ne soit suffisamment intelligent pour déterminer que les objets sont orphelins.
la source
Althrough java fournit la collecte des ordures automatique parfois vous voulez savoir la taille de l'objet est et combien il est laissé mémoire à l' aide .Gratuit programatically
import java.lang;
etRuntime r=Runtime.getRuntime();
pour obtenir des valeurs de mémoire à l' aidemem1=r.freeMemory();
d'appel de mémoire libre de lar.gc();
méthode et l'appelfreeMemory()
la source
La recommandation de JAVA est d'assigner à null
Depuis https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html
la source