【问题标题】:Need to call System.err.close() or JVM won't exit. Why?需要调用 System.err.close() 否则 JVM 不会退出。为什么?
【发布时间】:2011-06-26 22:32:30
【问题描述】:

我们有一个(非常)多线程的应用程序,它可以通过所有单元测试,但在从 IDE 或命令行运行时不会退出。这个应用程序不仅是多线程的,它还执行本机进程,并写入标准错误和标准输出。 问题是应用程序会在退出时挂起。最终,我减少了应用程序,直到它与单元测试相同,它仍然会挂起,所以,我认为 JUnit 正在做一些命令行启动所没有的事情。
当我在 main(args) 的末尾调用 System.exit() 时,应用程序将退出,这最终导致我进入 System.err.close()。
当然,应用程序永远不会“打开” System.err 或 System.out。它只是写入它们,并在完成时调用flush()。我只在 64 位 Windows 上测试过,稍后我将在 Linux 上测试。 JVM 是 Java(TM) SE 运行时环境(build 1.6.0_24-b07)

任何想法为什么 JVM 不会退出?

【问题讨论】:

    标签: jvm freeze standard-error


    【解决方案1】:

    我似乎记得,当您调用本机进程时,您必须小心地完全读取本机进程和/或错误流,否则事情可能会被锁定。我认为你可能需要产生一个线程来处理这个问题。只是一个想法。

    【讨论】:

    • 实际上这是很多代码的灵感来源。我们只是不知道,每当我们使用控制台时,都会使用它来关闭所有流。
    【解决方案2】:

    Linux 上的所有程序都在一定程度上面临这个问题。具有打开文件句柄的进程(您显然有一个,即使您没有专门打开一个,它来自您的系统命令操作之一)在所有句柄都关闭之前不会完全退出。目前我能想到的最好的例子是我在工作中遇到的一个问题,即启动 java 进程的启动脚本 (bash) 从未退出。问题是,我们正在执行 2>&1 > /path/to/log & ,它不会关闭标准输入(文件句柄 0)。将其链接到 &> /path/to/log 解决了问题,因为 &> 表示所有文件句柄,而另一个仅表示标准输入和标准错误。

    您的问题类似,而且它是多线程的事实加剧了问题。

    【讨论】:

    • 听起来不错。我们确实有代码可以读取 stderr 和 stdout 上的每个可用字符,但似乎一旦访问,我们必须显式关闭流。见鬼的副作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    相关资源
    最近更新 更多