2013-01-24 43 views
0

我們有一個使用jython執行一些python腳本的JavaEE應用程序。所使用的堆空間越來越大,直到沒有更多的剩餘空間。在heapdump中,我可以說有很多Py *類。通過過度使用Java來增加堆ScriptEngine(Jyhton)

所以我寫了一個小的測試程序: 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參數啓動此程序: -Xrs -Xms16M -Xmx16M -XX:MaxPermSize = 32M -XX:NewRatio = 3 -Dsun.rmi.dgc.client.gcInterval = 300000 -Dsun.rmi.dgc.server.gcInterval = 300000 -XX:+ UseConcMarkSweepGC -XX :+ UseParNewGC -XX:+ CMSPaRealRemarkEnabled -verbose:gc -XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps -server

這些是我們的AppServer運行的參數。在我的測試用例中只有Xms,Xmx和MaxPermSize較小。

當我運行這個應用程序時,我可以看到CMS Old Gen池增加到其最大尺寸。之後Par Parden Space池增加。此外,ParNewGC在任何時候都不再運行。清理部分改善了情況,但沒有解決問題。有沒有人有一個想法,爲什麼我的堆沒有完全清理?

回答

0

我想我已經找到了解決我的問題的方法:我刪除了JSR223的東西,現在直接使用PythonInterpreter。