Des exemples de la forcer à libérer de la mémoire natif direct ByteBuffer a alloué, à l'aide du soleil.misc.Dangereux?
JDK fournit abillity d'allouer des soi-disant direct ByteBuffers, où la mémoire est attribuée à l'extérieur du tas Java. Cela peut être bénéfique dans la mesure où cette mémoire n'est pas touché par le garbage collector, et, comme telle, ne contribue pas à la GC généraux: c'est un outil très utile pour les biens de longue durée de vie les choses comme les caches.
Cependant, il y a un problème essentiel dans la mise en œuvre existantes: sous-tendent la mémoire est allouée de manière asynchrone lorsque le propriétaire ByteBuffer est le garbage collector; il n'y a aucun moyen de forcer un début de libération de la mémoire. Cela peut être problématique, car GC cycle lui-même n'est pas influencée par la manipulation de ByteBuffers, et étant donné que ByteBuffers sont susceptibles de résider dans de Génération plus Ancienne zone de mémoire, il est possible que GC est appelé heures après ByteBuffer n'est plus en usage.
Mais en théorie, il devrait être possible d'utiliser sun.misc.Unsafe
méthodes (freeMemory, allocateMemory) directement: c'est ce que JDK utilise elle-même pour l'allocation/désallocation de mémoire natif.
En regardant le code, un souci que je vois est la possibilité de la double libération de mémoire -- donc je voudrait faire en sorte que l'etat serait d'être correctement nettoyé.
Quelqu'un peut-il m'indiquer le code qui fait cela? Dans l'idéal, l'souhaitez utiliser ce lieu de JNA.
REMARQUE: j'ai vu cette question qui est en quelque sorte liés.
Ressemble les réponses a souligné la bonne voie: ici est exemple de code à partir d'Élastiques de Recherche qui utilise l'idée. Grâce everyon!
- Il est possible, trouvé en sur SI il y a des années... à la recherche maintenant. (Dans le passé, j'ai fini juste à l'aide d'une file d'attente circulaire de tampons, qui a maintenu la pression basse dans mon cas.)
- Wow, je ne trouve pas de bons articles partout en ce moment 🙁
- Je n'ai pas encore vu un Système.gc() être ignoré, au moins sur le Soleil, qui semble être la cible de toute façon.
- Il y a un système de propriété pour faire de la JVM de l'ignorer, pour ce que ça vaut la peine.
- Le dernier lien est mort.
Vous devez vous connecter pour publier un commentaire.
À l'aide de
sun.misc.Unsafe
n'est guère possible en raison d'une adresse de base de la répartition de la mémoire natif est une variable locale dejava.nio.DirectByteBuffer
constructeur.En fait, vous pouvez forcer la libération de mémoire natif avec le code suivant:
Il y a un moyen beaucoup plus simple pour nettoyer la mémoire.
L'aide, il peut faire une grande différence, si vous êtes rejet direct ou mappés en mémoire ByteBuffer assez rapidement.
L'une des raisons d'utiliser le Nettoyant pour ce faire est que vous pouvez avoir plusieurs copies de la mémoire sous-jacente des ressources par exemple, avec slice(). et le robot dispose d'une ressource comte de ces.
sun.misc.Unsafe
en Java 9 ajoute unvoid invokeCleaner(ByteBuffer)
méthode.Fondamentalement, ce que vous voulez, c'est à la suite de la même sémantique que l'utilisation de IO ruisseaux. Tout comme vous avez besoin de fermer un flux une fois, vous avez besoin de libérer la mémoire à la fois. Donc vous pouvez écrire votre propre wrapper autour de la native appels de décisions au début de libérer de la mémoire possible