关于过大的占用内存的方法1

preview
需积分: 0 0 下载量 87 浏览量 更新于2022-08-08 收藏 16KB DOCX 举报
在Java编程中,有时我们需要在程序中执行外部命令,例如编译Java源代码(`javac`命令)。在标题和描述中提到的问题是关于如何正确地使用`Runtime.getRuntime().exec()`方法来避免内存占用过大或导致程序挂起的情况。这个问题的核心在于理解和处理子进程的输入、输出和错误流。 我们来看一下原始的`BadExecJavac2`程序。在这个例子中,`Runtime.exec("javac")`被用来执行没有参数的`javac`命令,这通常会打印出帮助信息。然而,这个程序没有任何输出并且似乎挂起,没有结束。原因在于,当执行外部命令时,Java会创建一个子进程,并且子进程的标准输出(stdout)和标准错误(stderr)会被连接到父进程的相应流。在本例中,由于没有读取子进程的输出,这些流可能会被填满,从而导致子进程阻塞,等待空间释放。在某些平台上,如果标准输入、输出或错误流的缓冲区大小有限,这种情况就会发生,甚至可能导致死锁。 为了解决这个问题,我们需要确保及时处理子进程的输出流。在`MediocreExecJavac`程序中,我们看到对子进程的错误流进行了正确的处理。通过以下步骤,我们可以避免子进程阻塞: 1. 获取子进程的错误流:`InputStream stderr = proc.getErrorStream();` 2. 创建一个`InputStreamReader`来读取错误流:`InputStreamReader isr = new InputStreamReader(stderr);` 3. 使用`BufferedReader`来读取并打印错误流中的每一行:`BufferedReader br = new BufferedReader(isr); while ( (line = br.readLine()) != null) System.out.println(line);` 这样,我们不仅读取了子进程的错误输出,还将其打印出来,避免了缓冲区溢出的问题。我们通过`proc.waitFor()`获取子进程的退出值,以确认命令是否成功执行。 在实际开发中,除了处理错误流,我们还需要考虑标准输出流(stdout)。如果子进程有输出到stdout,也需要进行类似的处理。此外,如果需要向子进程传递输入,可以使用`Process.getOutputStream()`获取子进程的输入流,并写入数据。 总结来说,使用`Runtime.exec()`执行外部命令时,必须注意处理子进程的输入、输出和错误流,以防止内存占用过大或程序挂起。这通常意味着需要创建`InputStreamReader`和`BufferedReader`来读取输出流,并确保及时处理它们,以保持子进程的正常运行。在Java中,正确地管理I/O流是避免这类问题的关键。