Java NIO MappedByteBuffer OutOfMemoryException
Bin ich wirklich ein Problem: ich Lesen möchte GROßE Dateien über mehrere GB mit FileChannel
s und MappedByteBuffer
s - alle Unterlagen, die ich gefunden impliziert, ist es ziemlich einfach zu Karte eine Datei mit der FileChannel.map()
Methode.
Natürlich gibt es eine Grenze bei 2GB, da alle Puffer Methoden Verwendung int position, limit und Kapazität - was aber das system impliziert die unten angegebenen Grenzwerte, dass?
In der Realität, ich bekomme jede Menge von Problemen in Bezug auf OutOfMemoryException
s! Und keine Dokumentation an alle, die wirklich definiert die Grenzen!
Also - wie kann ich die map eine Datei, die sich in die int-Grenze sicher in ein oder mehrere MappedByteBuffer
s ohne einfach nur Ausnahmen?
Kann ich Fragen, das system, die Teil einer Datei kann ich sicher ansehen, bevor ich versuche FileChannel.map()
? Wie?
Warum gibt es so wenig Dokumentation zu diesem feature??
Du musst angemeldet sein, um einen Kommentar abzugeben.
Je größer die Datei, desto weniger wollen Sie ihn alle im Speicher auf einmal. Entwickeln Sie ein Verfahren um die Datei einen Puffer zu einer Zeit, eine Zeile in einer Zeit, etc.
MappedByteBuffers sind besonders problematisch, da es keine definierten Freisetzung des zugeordneten Speicher, also mehr als ein zu einer Zeit ist im wesentlichen zum scheitern verurteilt.
Kann ich Ihnen ein paar funktionierenden code. Ob dies Ihr problem löst oder nicht, ist schwer zu sagen. Diese Jagden durch eine Datei für ein Muster erkannt, die durch die
Hunter
.Den hervorragenden Artikel Java-Tipp: Wie das Lesen von Dateien schnell für die ursprüngliche Forschung (nicht von mir).
Was ich benutze, ist ein
List<ByteBuffer>
wo jeder ByteBuffer Karten auf der Datei im block von 16 MB bis 1 GB. Ich verwendet eine Potenz von 2 ist zur Vereinfachung die Logik. Ich habe diese verwendet, um map-Dateien bis zu 8 TB.Eine wichtige Einschränkung des memory-mapped-Dateien ist, dass Sie nur durch den virtuellen Speicher. Wenn Sie eine 32-bit-JVM Sie nicht in der Lage auf Karte, sehr viel.
Ich würde nicht halten, die Schaffung neuer Speicher-mappings für eine Datei, denn diese werden nie gereinigt. Sie können erstellen, viele dieser, aber es scheint ein limit von etwa 32K von Ihnen auf einigen Systemen (egal wie klein Sie sind)
Den wichtigsten Grund finde ich MemoryMappedFiles nützlich ist, dass Sie nicht geleert werden müssen (wenn man davon ausgehen kann das OS wird nicht sterben), können Sie zum schreiben von Daten in eine niedrige Latenz Weg, ohne sich Gedanken über den Verlust von zu viel Daten, wenn die Anwendung stirbt oder zu viel Leistung durch write() oder flush().
cannot access the file
beim re-run mein Programm viele Male, von-scala-build-tool.buf = null ; System.gc
meinst du?Sie nicht die
FileChannel
- API zu schreiben, die gesamte Datei auf einmal. Stattdessen senden Sie die Datei in Teile. Siehe Beispiel-code in der Martin-Thompson-post-vergleichen der Leistung von Java-IO-Techniken: Java Sequentiellen IO-PerformanceDarüber hinaus gibt es nicht viel Dokumentation, da Sie eine Plattform-abhängige rufen. aus der
map()
JavaDoc: