我有一些關於ProcessBuilder的問題。該程序基本上是一個調用命令行腳本的簡單包裝器。java:ProcessBuilder使內存生豬
當通過終端自行運行腳本時,內存消耗保持在2G以下。 當通過java包裝器運行腳本時,內存消耗劇增,甚至8G很快填滿,導致內存不足錯誤。
啓動該過程的代碼只是:
public static int execute(String command) throws IOException
{
System.out.println("Executing: " + command);
ProcessBuilder pb = new ProcessBuilder(command.split(" +"));
Process p = pb.start();
// display any output in stderr or stdout
StreamConsumer stderr = new StreamConsumer(p.getErrorStream(), "stderr");
StreamConsumer stdout = new StreamConsumer(p.getInputStream(), "stdout");
new Thread(stderr).start();
new Thread(stdout).start();
try {
return p.waitFor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
的StreamConsumer類只是消耗標準輸出/ stderr流並在控制檯上顯示它們的類。
...問題是:爲什麼地球上的內存消耗會爆炸?
問候,
阿爾諾
編輯:
- 無論我使用的ProcessBuilder或 Runtime.getRuntime.exec(...),該 結果是一樣的。
- 爆發往往出現內存由 shell腳本調用UNIX '排序' 期間調用:
好吧,這裏:吉姆駐軍的請求
sort big-text-file > big-text-file.sorted
編輯2是我省略的StreamConsumer類,因爲它比較簡單:
class StreamConsumer implements Runnable
{
InputStream stream;
String descr;
StreamConsumer(InputStream stream, String descr) {
this.stream = stream;
this.descr = descr;
}
@Override
public void run()
{
String line;
BufferedReader brCleanUp =
new BufferedReader (new InputStreamReader (stream));
try {
while ((line = brCleanUp.readLine()) != null)
System.out.println ("[" + descr + "] " + line);
brCleanUp.close();
} catch (IOException e) {
// TODO: handle exception
}
}
}
只是一個猜測:如果StreamConsumer實際上沒有使用子進程的文本,那麼文本可能會保存在一個不斷增大的緩衝區中。 – 2010-09-14 12:01:43
所有stdout&stderr已成功顯示在控制檯中 – dagnelies 2010-09-14 12:03:10
如何測量內存消耗? _進程正在消耗內存...... JVM?貝殼?排序過程?在沒有看到StreamConsumer的情況下,很難知道那裏是否存在錯誤。你確定內存消耗對於進程是私有的還是僅僅是暫時的I/O緩衝區?你真的沒有提供太多的東西繼續下去。 – 2010-09-14 16:37:01