Frage

In meinem Programm dauert das Schließen eines java.util.randomaccessfile manchmal genau 45 Sekunden (fast genau: zwischen 44,998 und 45,003 Sekunden). Das Programm erstellt und schließt viele kleine Dateien. Normalerweise ist das Schließen der Datei sehr schnell (zwischen 0 und 0,1 Sekunden). Wenn ich das Programm debugge, steckt es in der nativen Methode RandomAccessfile.CLOSE0.

Das gleiche Problem tritt auch bei der Verwendung von FileOutputStream anstelle von randomAccessfile auf (in diesem Fall wird das Programm in der nativen Methode fileOutputStream blockiert.CLOSE0).

Hat jemand eine Idee, was das sein könnte? Können Sie das Problem in Ihrem System reproduzieren (ich kann es nur auf einem Mac reproduzieren, nicht unter Windows XP; ich habe noch nicht unter Linux getestet)?


Update 2:

Dies scheint nur auf Mac OS X zu glücklich zu sein. Ich verwende JDK 1.6.0_22-B04. Es passiert sowohl bei 32-Bit als auch bei 64-Bit. Unter Windows XP scheint es nicht zu sehen.

Mein Testfall ist:

import java.io.File;
import java.io.RandomAccessFile;
public class TestFileClose {
    public static void main(String... args) throws Exception {
        for (int i = 0; i < 100000; i++) {
            String name = "test" + i;
            RandomAccessFile r = new RandomAccessFile(name, "rw");
            r.write(0);
            long t = System.currentTimeMillis();
            r.close();
            long close = System.currentTimeMillis() - t;
            if (close > 200) {
                System.out.println("closing " + name +
                        " took " + close + " ms!");
            }
            if (i % 2000 == 0) {
                System.out.println("test " + i + "/100000");
            }
            new File(name).delete();
        }
    }
}

Beispielausgabe auf meiner Maschine:

test 0/100000
test 2000/100000
test 4000/100000
test 6000/100000
test 8000/100000
test 10000/100000
closing test10030 took 44998 ms!
test 12000/100000
test 14000/100000
test 16000/100000
closing test16930 took 44998 ms!
test 18000/100000
test 20000/100000
War es hilfreich?

Lösung

Es könnte Seien Sie McAfee Antivirus auf meiner Maschine installiert. Ich musste es installieren ... aber das Problem zeigt sich auch, wenn ich den On-Access-Scan deaktiviere.

Nur um zu überprüfen, ob es nicht Antivirus ist, ist jemand, der den Test auf seiner Maschine (ohne Antivirus) wiederholt und das gleiche Problem bekomme, denke ich.

Andere Tipps

Es könnte Seien Sie die Aktivität der Müllsammlung, ausgelöst durch Öffnen/Schließen einer großen Anzahl von RandomAccessFile Objekte; Es kann ungefähr 45 Sekunden lang nichts Magic geben - es könnte nur die Zeit sein, die das JVM auf Ihrer Maschine benötigt, um das Haufen zu durchqueren, damit Objekte frei sind. Trotzdem ist 45 Sekunden ein furchtbar lange GC -Pause; Eine Anwendung, an der ich kürzlich gearbeitet habe, erlitt immer eine volle GC von etwa 11 Sekunden.

Versuchen Sie, Ihr Programm mithilfe zu überwachen Jconsole oder Jvisualvm, oder wenn Sie das Programm starten, versuchen Sie die folgenden Optionen hinzuzufügen:

-verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

Dann schauen Sie in der gc.log Datei erstellt, um zu sehen, wie die Anwendungsstoppzeiten sind; Wenn Sie Ihren Code zum Drucken von Zeitstempeln instrumentieren, können Sie das möglicherweise verbinden close() Verhalten der spezifischen GC -Aktivität:

...
if (close > 200) {
    System.out.println(new Date());
    System.out.println("closing " + name +
                    " took " + close + " ms!");
}
...

Wenn es mit GC verwandt ist, in der gc.log Datei, Sie würden nach vollständigen Müllsammlungen und/oder Anwendungsstoppzeiten zu den Zeitstempeln suchen, die Ihr Programm ausgibt.

Basteln mit den Heap -Einstellungen (-Xmx=... und XX:MaxPermSize=...) kann Ihnen dann ein völlig anderes Profil geben.

Nebenbei bemerkt, wenn es sich um eine temporäre Datei handelt, versuchen Sie es mit der Verwendung File file = File.createTempFile(prefix, suffix) und geben das in die RandomAccessFile -Dies kann Dateien in /var /tmp (oder was auch immer genannt) auf OS X erstellt, wodurch ein In-Memory-Dateisystem anstelle eines diskbasierten Dateisystems verwendet wird.

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