Frage

Ich habe versucht, eine Art gemeinsamen Cache zwischen zwei oder mehreren JVMs von Speichern zu implementieren Abbilden eine bestimmte Datei mit MappedByteBuffer. Aus den Spezifikationen sehe ich, dass, wenn wir MappedByteBuffer.load() verwenden sollte die Daten in einen direkten Puffer laden. Ich habe ein paar Fragen zu diesem Thema.

Ihr Code-Snippet ::

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. Die Ausgabe des obigen Codes ist 0 Byte für den Direct Memory Usage (File.txt ist 1 GB). Aber wenn ich dazu die Zeile ..

    ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
    

    Ich bekomme eine Direct Memory Verwendung von 100MB. Nicht in der Lage zu verstehen, warum dies so ist, wie, warum ich keine direkte Speichernutzung an erster Stelle bekommen (das heißt, wenn die Leitung auf Kommentar)

  2. Obwohl die Direct Memory Usage 0 B für den obigen Code ist, sehe ich, dass der Bewohner Speicher (Unix oben unter Verwendung) des Verfahrens steigt um 1 GB. Aber wenn ich ein „freien -m“ tue auf dem Feld, ich sehe keinen Anstieg der Speichernutzung.

In beiden Fällen bin ich ein wenig verwirrt darüber, wo der Speicher bis endet.

Danke!

War es hilfreich?

Lösung

Direkt ByteBuffers (die zugewiesenen mit ByteBuffer.allocateDirect) unterschiedlich sind zu MappedByteBuffers, dass sie verschiedene Abschnitte des Speichers dar und sind unterschiedlich zugeordnet. Direkte ByteBuffers sind eine Möglichkeit, einen Speicherblock außerhalb der JVM im Allgemeinen mit einem malloc Anruf zugewiesen zugewiesen zuzugreifen (obwohl die meisten Implementierungen wahrscheinlich eine effiziente Platte allocator verwenden). D. h es ist nur ein Zeiger auf einen Speicherblock.

A MappedByteBuffer stellt einen Abschnitt des Speichers unter Verwendung von zugewiesenen Mmap Anruf, der verwendet wird, im Speicher abgebildeten E / A durchzuführen. Daher MappedByteBuffers nicht ihre Verwendung von Speichern in der gleichen Art und Weise wird ein direkter ByteBuffer registrieren.

Während also beide „direkt“, dass sie Speicher außerhalb der JVM repräsentieren ihre Zwecke unterschiedlich sind.

Als Nebenwirkung, um den reservedMemory Wert erhalten Sie reflexiv zu einem internen Verfahren der JVM aufrufen, deren Umsetzung wird von einer Spezifikation nicht abgedeckt, daher gibt es keine Garantien, was dieser Wert zurückgibt. Direkter ByteBuffers kann innerhalb JNI zugeordnet wird unter Verwendung von NewDirectByteBuffer Anruf von C / C ++ (MappedByteBuffers dies wahrscheinlich verwenden), und dies wahrscheinlich keinen Einfluss auf den reservedMemory Wert, der geändert nur, wenn das Java ByteBuffer.allocateDirect verwendet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top