Java GC日志文件句柄泄露给子进程

时间:2017-03-08 17:43:43

标签: java

我们使用JVM选项-verbose:gc-Xloggc:<path>将垃圾收集事件记录到文件中。正如所料,Java进程保持对GC日志文件的锁定。

奇怪的是,当我们生成子进程时,子进程也保持对GC日志文件的锁定。这是一个问题,因为当我们的主Java进程退出时,我们无法删除GC日志文件,直到子进程也退出。

这是令人惊讶的,因为Java在打开文件时应该使用标志FD_CLOEXEC以避免泄漏文件句柄到子进程。为什么GC日志文件不同?除禁用GC日志记录以外的任何解决方法吗?

下面的代码显示了一个简单的Java应用程序,它打开一个文件并启动一个在退出之前挂起3分钟的子进程。启用GC日志记录后,子进程会锁定GC日志文件(意外),但不会锁定常规文件my-file.log(预期)。

// VM options:
// -verbose:gc -Xloggc:C:/test/log/gc.log

public static void main(String[] args) throws InterruptedException, IOException {
    // Open a file for writing
    new FileOutputStream("C:\\test\\log\\my-file.log");

    // Start sub-process, but don't wait for it to exit
    List<String> command = Arrays.asList("C:\\test\\log\\wait_test.bat", "180");
    ProcessBuilder pb = new ProcessBuilder(command);
    Process childProcess = pb.start();

    // Wait 30 seconds
    Thread.sleep(30 * 1000L);

    // Exit without killing process or closing file
    System.out.println("Exiting with process running: " + childProcess.isAlive());
}

wait_test.bat的内容如下:

@echo off
REM %1 Time to wait in seconds
ping -n %1 localhost >nul

这是在Windows 7下使用Java版本1.8.0_101进行测试的。

更新:向JDK-8176717报告了Oracle的错误。

0 个答案:

没有答案