跳转至

进程

测试代码见代码库

子进程

Process blocking reason: The input stream and the error stream are separated, and if they are not processed, blocking will occur.

  • 创建的子进程的所有标准 io(即 stdin,stdout,stderr)操作通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程;
  • 有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁;
  • 标准输出流和错误流如果处理不当,其缓冲区不能被及时清除而被塞满,则进程被阻塞,即使调用Process.destory()也未必能销毁被阻塞的子进程

解决方案:

  • 并发获取Process的输出流和错误流;
  • 将错误流重定向到输出流;

环境变量

默认是继承 Java 进程的环境变量(等价于 System.getEnv)

父进程退出时Kill子进程

通过ProcessBuilder启动JVM,并注册kill父进程时执行的线程(kill子线程);

通过ProcessBuilder执行shell命令(如再启动java进程),此时通过jps查看会看到两个java进程;如果kill掉父进程,子进程不会随之消亡,若需要,需注册(见下面代码);

public class TestRunJVM {
    public static void main(String[] args) {
        ProcessBuilder pb = new ProcessBuilder("jvisualvm");
        try {
            final Process process = pb.start();
            // destroy child process,对于 kill -9 不生效
            Runtime.getRuntime().addShutdownHook(new Thread() {
                public void run() {
                    if (process != null) {
                        process.destroy();
                        try {
                            process.waitFor();
                        } catch (Exception e){
                            System.out.println("ERROR2" + e.toString());
                        }
                    }
                }
            });
            process.waitFor();
        } catch (Exception e) {
            System.out.println("ERROR" + e.toString());
        }
    }
}