如果父进程在启动后没有被销毁,Java process.start 的速度会极度减慢

发布于 2024-12-19 18:42:20 字数 715 浏览 4 评论 0原文

如果我直接从命令行启动特定进程,我会看到它在 2-3 秒内完全启动。

如果我使用 Java 程序中完全相同的命令启动完全相同的进程,它会在启动时挂起,除非父进程被销毁。为什么?

使用 ProcessBuilder:

ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(dir));
Process p = pb.start();

使用 Runtime.exec:

Runtime.getRuntime().exec(cmd, null, new File(dir));

无论哪种方式,如果我不将新 Process 对象设置为 null 并立即调用垃圾收集器,则新进程最多需要 3 分钟才能完成应在 3 秒内完成的相同操作。

Process p = pb.start();
p = null;
Runtime.getRuntime().gc();

使用上面的代码可以解决这个问题。有人可以解释一下为什么吗?我认为这与 JVM 进程处理有关,但这只是一个猜测。

新进程使用 Hibernate 连接到 MySQL 数据库,使用 log4j 写入日志文件,从 .properties 文件读取并连接到 RabbitMQ 服务器。

谢谢你,

祝你有美好的一天

If I start a particular process directly from command line, I see it completely starts in 2-3 seconds.

If I start the exact same process with the exact same command from a Java program, it hangs on start unless the parent is destroyed. Why?

With ProcessBuilder:

ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File(dir));
Process p = pb.start();

With Runtime.exec:

Runtime.getRuntime().exec(cmd, null, new File(dir));

Either way if I do not set the new Process object to null and call the garbage collector right away,the new process takes up to 3 minutes to do the same things it should do in 3 seconds.

Process p = pb.start();
p = null;
Runtime.getRuntime().gc();

Using the code above fixes the issue. Can someone explain me why? I think it's something related to the JVM an process handling but that's just a guess.

The new process uses Hibernate to connect to a MySQL DB, writes logfiles with log4j, reads from a .properties file and connects to a RabbitMQ server.

Thank you,

have a nice day

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄凉少年不暖心 2024-12-26 18:42:20

众所周知,从 Java 应用程序运行外部程序是非常困难的。

我建议使用高质量的 Apache Commons Exec 库

如果您想避免在代码中添加依赖项,至少请查看 Exec 库的 Java 代码 以查看它如何创建和运行进程。

Running external programs from Java applications is notoriously tricky to get right.

I recommend using the high quality Apache Commons Exec library.

If you want to avoid adding a dependency in your code, at least look at the Exec library's Java code to see how it creates and runs processes.

情愿 2024-12-26 18:42:20

也许您的子进程需要来自标准输入的一些输入?因此它会挂起,直到 p.getOutputStream().write() 提供输入

或者它可以等到它的 stdout 被消耗。

Maybe your child process needs some input from stdin? So it hangs until the input is provided by p.getOutputStream().write()

Or it can wait until its stdout will be consumed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文