JAVA web調用執行python腳本程序的四種方式,迴避java.lang.OutOfMemoryError:PermGen space內存溢出問題

我在網上搜到的JAVA調用python程序的三種方式:

方式一:調用python函數。可以傳入參數,獲取返回值。

                      public static void PythonFunctionTest(){
                        //python 解釋器
                        PythonInterpreter  interpreter = new PythonInterpreter();  
                        interpreter.execfile("E:\\Python_code\\helloPython.py");
                        PyFunction func=(PyFunction)interpreter.get("adder", PyFunction.class);
            
                        int a=2010;
                       int b=2;
                       PyObject pyobj = func.__call__(new PyInteger(a), new PyInteger(b));  
                       System.out.println("answer= "+pyobj.toString());
                     }
方式二:直接執行python腳本。不能傳參,不能獲取返回值。

                 public static void PythonTextTest()
                {
                   PythonInterpreter  interpreter = new PythonInterpreter();  
                   interpreter.execfile("E:/Python_code/helloPython1.py");
                }

方式三:在JAVA代碼裏面直接寫python程序,直接執行。這種方法顯然可以把參數傳進去,但是能不能獲得返回值需要進一步研究。

                 public static void PythonTest(){
                   PythonInterpreter interpreter =new PythonInterpreter();
                   interpreter.exec("days=('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday')");
                   interpreter.exec("print days[0]");
                }
考慮了一下,因爲第一種方式可以以調用函數的形式,同時即可以傳參又可以獲取返回值,所以我選擇了第一種方式用於在JAVA代碼塊中執行python程序。我在單獨的一個JAVA程序中執行相應代碼時,沒有問題,可以傳參也可以獲得返回的結果。但是當我把這段代碼放到現有的JAVAWEB的程序中時,會出現

java.lang.OutOfMemoryError:PermGen space內存溢出的問題。


於是我又按照網上的方法增到tomcat和eclipse的內存,結果無效。就這樣卡了很久後,我找到了第四種執行python程序的方法,這個方法不會產生內存溢出的問題。

方式四:使用控制檯執行python腳本,可以傳參和獲取返回值。

               public static String runTimeMethod(String name,String path) {
               try {
                    String cmd="python E:\\Python_code\\settingTest.py "+name+" "+path;
                    Process pr = Runtime.getRuntime().exec(cmd);
                    BufferedReader in = new BufferedReader(new InputStreamReader(
                    pr.getInputStream()));
                    String line="";
//輸出打印在控制檯上的結果            
//                  while ((line = in.readLine()) != null) {
//                  System.out.println(line);
//                 }
//得到打印在控制檯上的結果
                    while ((line = in.readLine()) != null) {
                    result+=line;
                   }
                   in.close();
                   pr.waitFor();
//                 System.out.println("end");
                   } catch (Exception e) {
                   e.printStackTrace();
                 }
                return result;
    }
其實這種方法就是在JAVA程序中執行控制檯命令,其效果等同於把
python E:\\Python_code\\settingTest.py  arg1 arg2
這段命令拷貝到cmd控制檯中。

雖然可以傳入參數或獲取返回值,但其實它的實現並不是特別靈活和好用。下面是我用於測試的python代碼。

#coding=utf-8
import json
import sys
def JsonTestForDownloadApks(name,path):
    print name,'   ',path 
name=sys.argv[1]
path=sys.argv[2]
JsonTestForDownloadApks(name,path)
可以看出,傳入參數的實現是通過python程序獲取控制檯輸入的方式。sys.arg[0]是當前python程序的執行路徑,sys.arg[1],sys.arg[2]是我們輸入的第一,二個參數。獲取返回結果是通過獲取打印到控制檯的輸出流獲的方式。其實這種方式有很大的侷限性,但是它起碼能迴避讓我頭疼的內存溢出問題,也能滿足我目前的功能需求,所以我選擇了這種方式。

PS.因爲我對python的知識幾乎一無所知,對於python和JAVA之間的調用也是現學現用,所以我上面所說的方法可能非常低級甚至存在很大的風險,僅供大家參考。



發佈了25 篇原創文章 · 獲贊 4 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章