10

java 5が永久世代を収集し、アプリがうまく動作するのに、Java 7が永久世代のアプリを収集できず、 java.lang.OutOfMemoryError: PermGen が発生する理由を知っている人はいますか?

アプリはループ内で jython 式の評価を行います。1 回の反復は約 1 回です。5秒 ループの本体は次のようになります。

PythonInterpreter py = new PythonInterpreter();
py.set("AI", 1);
((PyInteger)py.eval(expr)).getValue()

Java 7 および Java 5 で実行されているアプリ用に撮影された jvisual vm のスクリーンショット。

どちらの場合も、同じパラメーターが使用されます。

-Xmx700m 
-XX:MaxPermSize=100m
-XX:+HeapDumpOnOutOfMemoryError
-Xloggc:"C:\Temp\gc.log" -XX:+PrintGCDetails  -XX:-TraceClassUnloading -XX:+PrintClassHistogram 

ジャワ7 ジャワ5

4

2 に答える 2

2

問題を再現するための小さな例がありますが、Eclipseの外部でJava 7で実行されているプログラムは、永続的な生成でメモリリークの影響を受けないことがわかりました。

import org.python.core.PySystemState;
import org.python.util.PythonInterpreter;

public class Test01 {

  public static void main(String[] args) throws Exception  {
    PySystemState.initialize();
    long startNanos = System.nanoTime();
    for(int i = 0; i < 450000; i++)    {
        PythonInterpreter pi = new PythonInterpreter();
        long elapsedNanos = System.nanoTime() - startNanos;
        int avgStepInMicros = (int)((elapsedNanos / 1000) / (i+1));
        final String code = String.format(
                "stepNo = %d + 1\n" +
                "if stepNo %% 100 == 0:\n" + 
                "  print 'stepNo: %%d,  elapsedMillis: %%d, avgStepInMicros: %%d' %% (stepNo, %d, %d)", i, elapsedNanos/1000000, avgStepInMicros);
        pi.exec(code);
    }
  }
}

MATは、デバッガスレッドをガベージコレクタルートとして表示しました。

GCRoot

奇妙なことに、Java5のデバッグアプリにはこの問題はありません。

于 2012-08-16T08:08:54.037 に答える