Verhindern OutOfMemory bei der Verwendung von java.nio.MappedByteBuffer
Betrachten-Anwendung, die 5-6 threads, jeder thread in dem Zyklus zuordnen MappedByteBuffer für 5mb die Größe der Seite.
MappedByteBuffer b = ch.map(FileChannel.MapMode.READ_ONLY, r, 1024*1024*5);
Früher oder später, wenn die Anwendung funktioniert mit großen Dateien, oom ausgelöst
java.io.IOException: Map failed at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:758)
Caused by: java.lang.OutOfMemoryError: Map failed
at sun.nio.ch.FileChannelImpl.map0(Native Method)
at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:755)
Laut Spezifikation, MappedBuffer entsorgen sollte direct-memory-sobald es die GC selbst. Sieht aus wie das problem ist, dass MappedBuffer-s GC-ed zu spät, später dann direct memory fertig.
Wie Sie diese situation vermeiden ? Wahrscheinlich sagen MappedBuffer zu entsorgen implizit oder verwenden Sie eine Art pool von MappedBuffer
- Durch Neugier, was Ihr code tun?
- Die Ausnahme ist NICHT OOM aber IOException. Sie sind der virtuelle Adressraum. Zeigen Sie ein bisschen mehr code. Die zugeordneten Puffer und Rückgewinnung in java ist eine lange Zeit, Fragen (immer noch ungelöst aus)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie vermeiden, dass der Auslöser eine GC durch die Reinigung der zugeordneten byte-Puffer direkt.
Zur Verfügung gestellt nennen Sie diese, bevor Sie Sie verwerfen, Sie nicht run out of virtual memory.
Vielleicht können Sie einen Blick auf die Erstellung von größeren ByteBuffers weniger oft (es sei denn, Sie haben eine große Anzahl von Dateien) Erstellen eines MappedByteBuffer nicht frei ist (dauert etwa 50 Mikro-Sekunden auf einigen Maschinen)
Die Fehlermeldung sagt "map failed", nicht "heap space" oder "permgen space". Dies bedeutet, dass die JVM nicht genügend Adressraum zur Verfügung.
Sehen dieser Fehler in der Sonne die Datenbank, und auch diese Frage.
Der erste link bietet einen workaround (ewww), die nahe dem, was der zweite link sagt:
System.gc()
nennen könnte ein NOP. Mit-XX:+DisableExplicitGC
effektiv die hässlichen Flecken fangen die OOM und Wiederholung nach der GC AntragVielleicht ein
WeakHashMap
zu bündeln, um dieseMappedBuffers
funktionieren würde.Aber bevor Sie Vermutung über die Ursache, würde ich empfehlen, Einhaken Ihre app bis zu Visual VM 1.3.3, mit allen plugins installiert, so können Sie genau sehen, was der OOM Fehler. Du bist davon ausgegangen, dass diese MappedBuffers tun es, aber Sie sind nur 5MB für jeweils 5-6 threads - 25-30MB insgesamt.
Bessere Daten haben als eine Vermutung. Visual VM wird es für Sie.
WeakHashMap
ist völlig nutzlos/schädlich, da der Schlüssel nicht der Puffer selbst, daher ist es nicht auch ein GC-verfügbar sind, bevor dasWeakHashMap
ist gestrichen (intern). Mit einem GC-abhängige Struktur für das problem ist definitiv falsch.Gar nicht wirklich sagen, dass überall dort, wo ich das sehen kann. Es ist ein langjähriger Bug Parade Element, das sagt, es ist nie veröffentlicht.
Tut es sagen: