Domanda

Stavo cercando di implementare una sorta di cache condivisa tra due o più JVM mediante la mappatura della memoria di un determinato file utilizzando MappedByteBuffer . Dalle specifiche vedo che quando usiamo MappedByteBuffer.load () dovrebbe caricare i dati in un buffer diretto. Ho un paio di domande su questo.

Il mio frammento di codice ::

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. L'output del codice precedente è 0 byte per l'utilizzo diretto della memoria (File.txt è 1 GB). Ma se rimuovo il commento ..

    ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
    

    Ottengo un utilizzo diretto della memoria di 100 MB. Non riesco a capire perché sia ??così, in primo luogo perché non ottengo alcun utilizzo diretto della memoria (ovvero quando la riga viene commentata)

  2. Sebbene l'utilizzo della memoria diretta sia 0 B per il codice sopra, vedo che la memoria residente (usando unix top) del processo aumenta di 1 GB. Ma se faccio un " free -m " sulla confezione non vedo alcun aumento nell'utilizzo della memoria.

In entrambi i casi, sono un po 'confuso su dove finisca la memoria.

Grazie!

È stato utile?

Soluzione

Direct ByteBuffers (quelli allocati utilizzando ByteBuffer.allocateDirect) sono diversi da MappedByteBuffers in quanto rappresentano sezioni di memoria diverse e sono allocate in modo diverso. I ByteBuffer diretti sono un modo per accedere a un blocco di memoria allocato al di fuori della JVM generalmente allocato con una chiamata malloc (sebbene la maggior parte delle implementazioni utilizzerà probabilmente un efficiente allocatore di lastre). Cioè è solo un puntatore a un blocco di memoria.

Un MappedByteBuffer rappresenta una sezione di memoria allocata utilizzando la chiamata mmap , che viene utilizzata per eseguire l'I / O mappato in memoria. Pertanto MappedByteBuffers non registrerà il loro uso della memoria allo stesso modo di un Direct ByteBuffer.

Quindi, mentre entrambi sono "diretti" in quanto rappresentano la memoria al di fuori della JVM i loro scopi sono diversi.

A parte questo, al fine di ottenere il valore riservatoMemoria, si sta riflettendo in modo riflessivo su un metodo interno della JVM, la cui implementazione non è coperta da alcuna specifica, quindi non ci sono garanzie su ciò che quel valore restituisce. I ByteBuffer diretti possono essere allocati all'interno di JNI utilizzando Chiamata NewDirectByteBuffer da C / C ++ (Probabilmente MappedByteBuffers lo utilizza) e questo probabilmente non influisce sul valore riservatoMemory, che può essere modificato solo quando si utilizza Java ByteBuffer.allocateDirect.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top