6

OutOfMemoryError結果をファイルにフラッシュして を呼び出すことができるように、 に本当に近づいたときを知る必要がありますruntime.gc();。私のコードは次のようなものです:

Runtime runtime = Runtime.getRuntime();
...
if ((1.0 * runtime.totalMemory() / runtime.maxMemory()) > 0.9) {
... flush results to file ...
  runtime.gc();
}

これを行うより良い方法はありますか?誰か手を貸してくれませんか?

編集

私はこのように火遊びをしていることを理解していたので、私は十分に食べたときを判断するためのより堅実で簡単な方法を考えました. 私は現在 Jena モデルで作業しているので、簡単なチェックを行います。モデルに 550k を超えるステートメントがある場合は、リスクを冒さないようにフラッシュします。

4

2 に答える 2

1

これはうまくいくようです:

public class LowMemoryDetector {

    // Use a soft reference to some memory - will be held onto until GC is nearly out of memory.
    private final SoftReference<byte[]> buffer;
    // The queue that watches for the buffer to be discarded.
    private final ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
    // Have we seen the low condition?
    private boolean seenLow = false;

    public LowMemoryDetector(int bufferSize) {
        // Make my buffer and add register the queue for it to be discarded to.
        buffer = new SoftReference(new byte[bufferSize], queue);
    }

    /**
     * Please be sure to create a new LMD after it returns true.
     * 
     * @return true if a memory low condition has been detected.
     */
    public boolean low () {
        // Preserve that fact that we've seen a low.
        seenLow |= queue.poll() != null;
        return seenLow;
    }
}

private static final int OneMeg = 0x100000;

public void test() {
    LowMemoryDetector lmd = new LowMemoryDetector(2*OneMeg);
    ArrayList<char[]> eatMemory = new ArrayList<>();
    int ate = 0;
    while ( !lmd.low() ) {
        eatMemory.add(new char[OneMeg]);
        ate += 1;
    }
    // Let it go.
    eatMemory = null;
    System.out.println("Ate "+ate);
}

それは印刷します

Ate 1070

私のため。

使用している最大のアロケーション ユニットよりも大きなバッファー サイズを使用します。バッファーが解放された場合に割り当て要求が満たされるように、十分な大きさが必要です。

64 ビット JVM では、大量のメモリを使用して実行している可能性があることに注意してください。この場合、このアプローチはほぼ確実に多くの問題に直面します。

于 2014-03-04T11:50:14.137 に答える