0

jython を使用していくつかの Python スクリプトを実行する JavaEE アプリケーションがあります。ヒープスペースがなくなるまで、使用済みのヒープスペースはどんどん大きくなります。ヒープダンプを見ると、Py* クラスがたくさんあることが分かります。

だから私は小さなテストプログラムを書きました:TestApp

public class TestApp {
    private final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    private HashMap<String, ScriptEngine> scriptEngines = new HashMap<String, ScriptEngine>();
    private final String scriptContainerPath = "";

    public static void main(String[] args) throws InterruptedException {
        int counter = 1;
        while(true) {
            System.out.println("iteration: " + counter);
            TestApp testApp = new TestApp();
            testApp.execute();
            counter++;
            Thread.sleep(100);
        }
    }

    void execute() {
        File scriptContainer = new File(scriptContainerPath);
        File[] scripts = scriptContainer.listFiles();
        if (scripts != null && scripts.length > 0) {
            Arrays.sort(scripts, new Comparator<File>() {
                @Override
                public int compare(File file1, File file2) {
                    return file1.getName().compareTo(file2.getName());
                }
            });

            for (File script : scripts) {

                String engineName = ScriptExecutor.getEngineNameByExtension(script.getName());
                if(!scriptEngines.containsKey(engineName)) {
                    scriptEngines.put(engineName, scriptEngineManager.getEngineByName(engineName));
                }
                ScriptEngine scriptEngine = scriptEngines.get(engineName);

                try {
                    ScriptExecutor scriptExecutor = new ScriptExecutor(scriptEngine, script, null);
                    Boolean disqualify = scriptExecutor.getBooleanScriptValue("disqualify");
                    String reason = scriptExecutor.getStringScriptValue("reason");
                    System.out.println("disqualify: " + disqualify);
                    System.out.println("reason: " + reason);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            // cleanup
            for(Map.Entry<String, ScriptEngine> entry : scriptEngines.entrySet()) {
                ScriptEngine engine = entry.getValue();             
                engine.getContext().setErrorWriter(null);
                engine.getContext().setReader(null);
                engine.getContext().setWriter(null);
            }
        }
    }
}

ScriptExecutor

public class ScriptExecutor {
    private final static String pythonExtension = "py";
    private final static String pythonEngine = "python";
    private final ScriptEngine scriptEngine;

    public ScriptExecutor(ScriptEngine se, File file, Map<String, Object> keyValues) throws FileNotFoundException, ScriptException {
        scriptEngine = se;
        if (keyValues != null) {
            for (Map.Entry<String, Object> entry : keyValues.entrySet()) {
                scriptEngine.put(entry.getKey(), entry.getValue());
            }
        }
        // execute script
        Reader reader = null;
        try {
            reader = new FileReader(file);
            scriptEngine.eval(reader);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // nothing to do
                }
            }
        }
    }

    public Boolean getBooleanScriptValue(String key) {
        // convert Object to Boolean
    }

    public String getStringScriptValue(String key) {
        // convert Object to String
    }

    public static String getEngineNameByExtension(String fileName) {
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1);

        if (pythonExtension.equalsIgnoreCase(extension)) {
            System.out.println("Found engine " + pythonEngine + " for extension " + extension + ".");
            return pythonEngine;
        }
        throw new RuntimeException("No suitable engine found for extension " + extension);
    }
}

指定されたディレクトリには、すべて次のような 14 個の Python スクリプトがあります。

disqualify = True
reason = "reason" 

このプログラムを次の VM 引数で開始します。 gcInterval=300000 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -server

これらは、AppServer が実行されている引数です。私のテストケースでは、Xms、Xmx、および MaxPermSize のみが小さくなっています。

このアプリケーションを実行すると、CMS Old Gen プールが最大サイズまで増加することがわかります。その後、Par Eden Space プールが増加します。さらに、いつでも ParNewGC は実行されなくなります。クリーンアップの部分で状況は改善されましたが、問題は解決しませんでした。私のヒープが完全にクリーンアップされていない理由を誰か知っていますか?

4

1 に答える 1

0

私の問題の解決策を見つけたと思います.JSR223のものを削除し、PythonInterpreterを直接使用するようになりました.

于 2013-02-22T07:57:59.870 に答える