Est-il possible de forcer le ramasse-miettes en Java, même si c'est délicat à faire? Je connais System.gc();
et Runtime.gc();
mais ils suggèrent seulement de faire GC. Comment puis-je forcer le GC?
java
garbage-collection
Robert Columbia
la source
la source
Réponses:
Votre meilleure option est d'appeler
System.gc()
ce qui est simplement un indice pour le garbage collector que vous voulez qu'il fasse une collecte. Il n'y a aucun moyen de forcer et de collecter immédiatement, car le garbage collector n'est pas déterministe.la source
non-deterministic == trouble
GC.Collect()
ne recueille pas. En Javagc()
fait.La bibliothèque jlibs a une bonne classe utilitaire pour la récupération de place . Vous pouvez forcer la collecte des ordures à l'aide d'une astuce astucieuse avec des objets WeakReference .
RuntimeUtil.gc () des jlibs:
la source
PhantomReference
avec unReferenceQueue
et ensuite vous seriez averti après la finalisation, mais toujours avant le nettoyage. Enfin, même si vous avez détecté avec succès que la mémoire de cet objet a été récupérée, cela signifierait encore très peu dans un GC générationnel comme HotSpot. Habituellement, cela coïncidait avec le nettoyage de la jeune génération.System.gc(); System.gc();
, mais il serait certainement intéressant de savoir si cela a jamais fonctionné mieux que cela. En fait, il suffit d’imprimer le nombre de fois qu’il a appeléSystem.gc()
. La chance d'atteindre jamais 2 est assez mince.La meilleure (sinon la seule) façon de forcer un GC serait d'écrire une JVM personnalisée. Je crois que les collecteurs de déchets sont enfichables, vous pouvez donc probablement choisir l'une des implémentations disponibles et la modifier.
Remarque: ce n'est PAS une réponse facile.
la source
À l'aide de l' interface Java ™ Virtual Machine Tool (JVM TI) , la fonction
"Force la machine virtuelle à effectuer une récupération de place". La JVM TI fait partie de l' architecture de débogage de plate-forme JavaTM (JPDA) .
la source
OUI il est presque possible de forcer vous devez appeler des méthodes dans le même ordre et en même temps celles-ci sont:
même s'il n'y a qu'un seul objet à nettoyer, l'utilisation de ces deux méthodes en même temps force le garbage collector à utiliser la
finalise()
méthode de l'objet inaccessible en libérant la mémoire affectée et en faisant ce que lafinalize()
méthode indique.TOUTEFOIS, c'est une pratique terrible d'utiliser le garbage collector car son utilisation pourrait introduire une surcharge du logiciel qui peut être pire que celle de la mémoire, le garbage collector a son propre thread qui n'est pas possible de contrôler plus en fonction de l'algorithme utilisé par le gc pourrait prendre plus de temps et est considéré comme très inefficace, vous devriez vérifier votre logiciel s'il est pire avec l'aide du gc car il est définitivement cassé, une bonne solution ne doit pas dépendre du gc.
REMARQUE: juste pour garder à l'esprit que cela ne fonctionnera que si dans la méthode de finalisation n'est pas une réaffectation de l'objet, si cela se produit, l'objet restera en vie et il aura une résurrection qui est techniquement possible.
la source
gc()
n'est qu'un indice pour exécuter un garbage collection.runFinalizers()
exécute uniquement les finaliseurs sur les objets "dont on a constaté qu'ils étaient rejetés". Si le GC n'a pas réellement fonctionné, il n'y a peut-être pas de tels objets ...Dans la documentation d' OutOfMemoryError, il déclare qu'il ne sera pas jeté à moins que la machine virtuelle n'ait pas réussi à récupérer de la mémoire après un garbage collection complet. Donc, si vous continuez d'allouer de la mémoire jusqu'à ce que vous obteniez l'erreur, vous aurez déjà forcé une récupération de place complète.
Vraisemblablement, la question que vous vouliez vraiment poser était "comment puis-je récupérer la mémoire que je pense que je devrais récupérer par la collecte des ordures?"
la source
Pour demander manuellement GC (pas à partir de System.gc ()):
la source
.gc est un candidat à l'élimination dans les versions futures - un ingénieur Sun a un jour déclaré que peut-être moins de vingt personnes dans le monde savent réellement comment utiliser .gc () - j'ai fait du travail la nuit dernière pendant quelques heures sur une centrale / critique structure de données utilisant des données générées par SecureRandom, quelque part juste après 40 000 objets, la VM ralentirait comme si elle était à court de pointeurs. De toute évidence, il étouffait les tables de pointeurs 16 bits et présentait un comportement classique de "machines défaillantes".
J'ai essayé -Xms et ainsi de suite, j'ai continué à tourner jusqu'à ce qu'il atteigne environ 57, xxx quelque chose. Ensuite, il exécuterait gc allant de disons 57.127 à 57.128 après un gc () - à peu près au rythme du code au camp Easy Money.
Votre conception nécessite une refonte fondamentale, probablement une approche de fenêtre coulissante.
la source
Vous pouvez déclencher un GC à partir de la ligne de commande. Ceci est utile pour batch / crontab:
Voir:
la source
La spécification JVM ne dit rien de spécifique sur la récupération de place. Pour cette raison, les fournisseurs sont libres d'implémenter GC à leur manière.
Ce flou entraîne donc une incertitude dans le comportement de collecte des ordures. Vous devriez vérifier les détails de votre JVM pour connaître les approches / algorithmes de récupération de place. Il existe également des options pour personnaliser le comportement.
la source
Si vous devez forcer la récupération de place, vous devriez peut-être réfléchir à la façon dont vous gérez les ressources. Créez-vous de gros objets qui persistent dans la mémoire? Créez-vous des objets volumineux (par exemple, des classes graphiques) qui ont une
Disposable
interface et n'appelez-vous pasdispose()
lorsque vous en avez terminé? Déclarez-vous quelque chose au niveau de la classe dont vous n'avez besoin que dans une seule méthode?la source
Il serait préférable de décrire la raison pour laquelle vous avez besoin d'un ramasse-miettes. Si vous utilisez SWT, vous pouvez disposer de ressources telles que
Image
etFont
pour libérer de la mémoire. Par exemple:Il existe également des outils pour déterminer les ressources non utilisées.
la source
Si vous manquez de mémoire et que
OutOfMemoryException
vous en obtenez un, vous pouvez essayer d'augmenter la quantité d'espace disponible sur java en démarrant votre programme avecjava -Xms128m -Xmx512m
au lieu de simplementjava
. Cela vous donnera une taille de tas initiale de 128 Mo et un maximum de 512 Mo, ce qui est bien plus que le 32 Mo / 128 Mo standard.la source
java -Xms512M -Xmx1024M
Une autre option consiste à ne pas créer de nouveaux objets.
Le regroupement d'objets est loin pour réduire le besoin de GC en Java.
Le regroupement d'objets ne va généralement pas être plus rapide que la création d'objets (en particulier pour les objets légers) mais il est plus rapide que Garbage Collection. Si vous avez créé 10 000 objets et que chaque objet faisait 16 octets. C'est 160 000 octets que GC doit récupérer. D'un autre côté, si vous n'avez pas besoin de tous les 10000 en même temps, vous pouvez créer un pool pour recycler / réutiliser les objets, ce qui élimine le besoin de construire de nouveaux objets et élimine le besoin d'anciens objets GC.
Quelque chose comme ça (non testé). Et si vous voulez qu'il soit sûr pour les threads, vous pouvez échanger la LinkedList contre une ConcurrentLinkedQueue.
la source
Sur OracleJDK 10 avec G1 GC, un seul appel à
System.gc()
provoquera le nettoyage de l'ancienne collection par GC. Je ne sais pas si GC fonctionne immédiatement. Cependant, GC ne nettoiera pas la Young Collection même si elleSystem.gc()
est appelée plusieurs fois dans une boucle. Pour que GC nettoie la Young Collection, vous devez allouer en boucle (par exemplenew byte[1024]
) sans appelerSystem.gc()
. L'appelSystem.gc()
pour une raison quelconque empêche GC de nettoyer la collection Young.la source
C'est correct, seulement un geste. Vous avez à peu près les réponses standard déjà données par plusieurs affiches. Prenons celui-ci un par un:
Exact, il n'y a pas de jvm réel - ce n'est qu'une spécification, un tas d'informatique décrivant un comportement souhaité ... J'ai récemment creusé l'initialisation des objets Java à partir du code natif. Pour obtenir ce que vous voulez, la seule façon est de faire ce que l'on appelle une annulation agressive. Les erreurs si mal faites sont si mauvaises que nous devons nous limiter à la portée initiale de la question:
La plupart des affiches ici supposeront que vous dites que vous travaillez sur une interface, si tel est le cas, nous devrions voir si vous recevez l'objet entier ou un élément à la fois.
Si vous n'avez plus besoin d'un objet, vous pouvez attribuer null à l'objet mais si vous vous trompez, une exception de pointeur null est générée. Je parie que vous pouvez obtenir un meilleur travail si vous utilisez NIO
Chaque fois que vous ou moi ou quelqu'un d'autre obtient: " S'il vous plaît, j'en ai horriblement besoin. " C'est un précurseur presque universel de la destruction presque totale de ce sur quoi vous essayez de travailler .... écrivez-nous un petit exemple de code, aseptisant de tout code réel utilisé et montrez-nous votre question.
Ne soyez pas frustré. Souvent, cela résout le problème: votre dba utilise un package acheté quelque part et la conception d'origine n'est pas modifiée pour les structures de données massives.
C'est très courant.
la source
FYI
L'appel de méthode System.runFinalizersOnExit (true) garantit que les méthodes du finaliseur sont appelées avant l'arrêt de Java. Cependant, cette méthode est intrinsèquement dangereuse et a été déconseillée. Une alternative consiste à ajouter des «hooks d'arrêt» avec la méthode Runtime.addShutdownHook.
Masarrat Siddiqui
la source
Il existe un moyen indirect de forcer le ramasse-miettes. Il vous suffit de remplir le tas d'objets temporaires jusqu'au moment où le garbage collector s'exécutera. J'ai fait une classe qui force le garbage collector de cette façon:
Usage:
Je ne sais pas à quel point cette méthode est utile, car elle remplit constamment le tas, mais si vous avez une application critique qui DOIT forcer GC - quand cela peut être la manière portable Java de forcer GC.
la source
Je voudrais ajouter quelque chose ici. Veuillez noter que Java ne fonctionne pas sur une machine virtuelle et non sur une machine réelle. La machine virtuelle a son propre moyen de communication avec la machine. Il peut varier d'un système à l'autre. Maintenant, lorsque nous appelons le GC, nous demandons à la machine virtuelle de Java d'appeler le garbage collector.
Étant donné que le garbage collector est avec une machine virtuelle, nous ne pouvons pas le forcer à effectuer un nettoyage sur place. Plutôt que nous mettons en file d'attente notre demande avec le garbage collector. Cela dépend de la machine virtuelle, après un temps particulier (cela peut changer d'un système à l'autre, généralement lorsque la mémoire de seuil allouée à la JVM est pleine), la machine réelle libérera de l'espace. :RÉ
la source
Le code suivant est extrait de la méthode assertGC (...). Il essaie de forcer le ramasse-miettes non déterministe à collecter.
Source (j'ai ajouté quelques commentaires pour plus de clarté): Exemple NbTestCase
la source
Vous pouvez essayer d'utiliser
Runtime.getRuntime().gc()
ou d'utiliser une méthode utilitaireSystem.gc()
Remarque: Ces méthodes ne garantissent pas le GC. Et leur portée doit être limitée à la JVM plutôt que de la gérer par programme dans votre application.la source
Si vous utilisez JUnit et Spring, essayez d'ajouter ceci dans chaque classe de test:
la source