Tengo algunos problemas con respecto a ProcessBuilder. El programa es básicamente un envoltorio simple que invoca un script de línea de comandos.java: ProcessBuilder hace una memoria de cerdo
Al ejecutar el script solo a través del terminal, el consumo de memoria se mantiene por debajo de 2G. Al ejecutar el script a través del contenedor java, el consumo de memoria explota e incluso 8G se llena rápidamente, lo que produce errores de memoria insuficiente.
El código para poner en marcha el proceso es simple:
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);
}
}
clase El StreamConsumer es simplemente una clase que consume las corrientes/stderr stdout y mostrarlos en la consola.
... la pregunta es: ¿por qué el consumo de memoria explota?
Saludos,
Arnaud
Editar:
- Si utilizo ProcessBuilder o Runtime.getRuntime.exec (...), el resultado es el mismo .
- La memoria estallidos tienden a aparecer durante Unix 'especie' invocada por el guión shell llamado:
sort big-text-file > big-text-file.sorted
Editar 2 en la petición de Jim Garrison:
Ok, aquí es la clase de StreamConsumer que omití porque es bastante simple:
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
}
}
}
Solo una suposición: si StreamConsumer no consume el texto del subproceso, el texto se puede mantener en un búfer que aumenta constantemente de tamaño. –
Todos stdout y stderr se muestran con éxito en la consola – dagnelies
¿Cómo se está midiendo el consumo de memoria? _¿Qué proceso está consumiendo la memoria ... la JVM? ¿La cáscara? El proceso de clasificación? Sin ver StreamConsumer es difícil saber si hay algún error allí. ¿Está seguro de que el consumo de memoria es privado para el proceso o solo son búferes de E/S transitorias? Realmente no has proporcionado mucho para continuar aquí. –