2013-01-24 3 views
0

우리는 jython을 사용하여 파이썬 스크립트를 실행하는 JavaEE 애플리케이션을 보유하고 있습니다. 사용 된 힙 스페이스는 더 이상의 힙 스페이스가 없어 질 때까지 점점 더 커집니다. heapdump에서 많은 Py * 클래스가 있다는 것을 알 수 있습니다.Java ScriptEngine (Jyhton)의 과도한 사용으로 힙이 증가합니다

disqualify = True 
reason = "reason" 
:

가 지정된 디렉토리에서 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); 
    } 
} 

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); 
      } 
     } 
    } 
} 

모두는 다음과 같이 14 파이썬 스크립트입니다 TestApp가 :

그래서 나는 작은 테스트 프로그램을 작성

다음 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 : + CMSParallelRemarkEnabled -verbose : gc -XX : + PrintGCDetails -XX : + PrintGCTimeStamps -server

다음은 AppServer가 실행되는 인수입니다. 내 테스트 케이스에서는 Xms, Xmx 및 MaxPermSize 만 작습니다.

이 응용 프로그램을 실행하면 CMS Old Gen 풀이 최대 크기로 증가한다는 것을 알 수 있습니다. 그 후에 Par Eden Space 풀이 증가합니다. 또한 언제든지 ParNewGC가 더 이상 실행되지 않습니다. 정리 부분은 상황을 개선했지만 문제를 해결하지 못했습니다. 내 힙이 완전하게 정리되지 않은 이유를 누구나 알고 있습니까?

답변

0

내 문제에 대한 해결책을 찾았습니다. JSR223을 제거하고 이제는 PythonInterpreter를 직접 사용합니다.

관련 문제