Question

J'essayais d'implémenter une sorte de cache partagé entre deux ou plusieurs machines virtuelles Java en mappant en mémoire un fichier particulier à l'aide de MappedByteBuffer . D'après les spécifications, je vois que lorsque nous utilisons MappedByteBuffer.load () , il convient de charger les données dans un tampon direct. J'ai quelques questions à ce sujet.

Mon extrait de code ::

RandomAccessFile file = new RandomAccessFile("file.txt","rw");
FileChannel fc = file.getChannel();
MappedByteBuffer buf5 = fc.map(MapMode.READ_WRITE, 0, fc.size());

//ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);

buf5.load();

try
{
    Class c = Class.forName("java.nio.Bits");
    Field f = c.getDeclaredField("reservedMemory");
    f.setAccessible(true);
    long reservedMemory = f.getLong(null);
    f = c.getDeclaredField("maxMemory");
    f.setAccessible(true);
    System.out.println(
            "Direct Memory Usage: "+ reservedMemory +"/"+ f.getLong(null)+"\n");
}
catch (Throwable t)
{
}
  1. La sortie du code ci-dessus est 0 octet pour l'utilisation directe de la mémoire (fichier.txt est égal à 1 Go). Mais si je décommenter la ligne.

    ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
    

    Je reçois une utilisation directe de la mémoire de 100 Mo. Incapable de comprendre pourquoi il en est ainsi, pourquoi je n’obtiens pas d’utilisation directe de la mémoire (c’est-à-dire lorsque la ligne est commentée)

  2. Bien que l'utilisation directe de la mémoire soit de 0 B pour le code ci-dessus, je constate que la mémoire résidente (en utilisant unix top) du processus augmente de 1 Go. Mais si je fais un "free -m" sur la boîte, je ne vois aucune augmentation de l’utilisation de la mémoire.

Dans les deux cas, je suis un peu confus quant à la destination finale de la mémoire.

Merci!

Était-ce utile?

La solution

Les ByteBuffers directs (ceux attribués à l'aide de ByteBuffer.allocateDirect) sont différents des MappedByteBuffers car ils représentent différentes sections de la mémoire et sont alloués différemment. Les ByteBuffers directs sont un moyen d'accéder à un bloc de mémoire alloué en dehors de la machine virtuelle Java généralement alloué avec un appel malloc (bien que la plupart des implémentations utilisent probablement un allocateur de brames efficace). C'est à dire. c'est juste un pointeur sur un bloc de mémoire.

Un MappedByteBuffer représente une partie de la mémoire allouée à l’aide de l’appel mmap , qui est utilisée pour effectuer des E / S mappées en mémoire. Par conséquent, MappedByteBuffers n'enregistrera pas leur utilisation de la mémoire de la même manière qu'un Direct ByteBuffer le fera.

Ainsi, alors que les deux sont "directs" en ce sens qu'ils représentent une mémoire en dehors de la machine virtuelle, leurs objectifs sont différents.

Soit dit en passant, pour obtenir la valeur reservedMemory, vous appelez de manière réflexive une méthode interne de la machine virtuelle Java, dont la mise en œuvre n'est couverte par aucune spécification. Par conséquent, rien ne garantit ce que cette valeur renvoie. Les ByteBuffers directs peuvent être attribués depuis JNI à l'aide de NewDirectByteBuffer à partir de C / C ++ (MappedByteBuffers l’utilisera probablement) et cela n’affectera probablement pas la valeur reservedMemory, qui ne peut être modifiée que lors de l’utilisation de Java ByteBuffer.allocateDirect.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top