You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux系统下java.io.PrintStream阻塞致Selenium Java应用挂起问题

问题分析与解决方案

线程转储信息

"Exec Stream Pumper" daemon prio=5 id=126 state=BLOCKED
LockOwnerName= pool-1-thread-9 LockOwnerId=129 LockName=java.io.PrintStream@27c7422a
BlockedTime= -1 BlockedCount= 1
     at java.io.PrintStream.write(PrintStream.java:447)
     at org.openqa.selenium.io.MultiOutputStream.write(MultiOutputStream.java:40)
     at java.io.OutputStream.write(OutputStream.java:116)
     at org.apache.commons.exec.StreamPumper.run(StreamPumper.java:108)
     at java.lang.Thread.run(Thread.java:750)
"Forwarding quit on session ea6c16f7-a829-4711-a058-e0cae7f49447 to remote"  prio=5 id=122 state=BLOCKED
LockOwnerName= pool-1-thread-9 LockOwnerId=129 LockName=java.io.PrintStream@27c7422a
BlockedTime= -1 BlockedCount= 10
     at java.io.PrintStream.flush(PrintStream.java:337)
     at org.openqa.selenium.io.MultiOutputStream.flush(MultiOutputStream.java:48)
     at org.apache.commons.exec.PumpStreamHandler.stop(PumpStreamHandler.java:195)
     at org.openqa.selenium.os.OsProcess.destroy(OsProcess.java:135)
     at org.openqa.selenium.os.CommandLine.destroy(CommandLine.java:139)
     at org.openqa.selenium.remote.service.DriverService.stop(DriverService.java:281)
     at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:129)
     at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:541)
     at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:596)
     at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:600)
     at org.openqa.selenium.remote.RemoteWebDriver.quit(RemoteWebDriver.java:443)
     at org.openqa.selenium.firefox.FirefoxDriver.quit(FirefoxDriver.java:307)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at org.openqa.selenium.support.events.EventFiringWebDriver.lambda$new$1(EventFiringWebDriver.java:106)
     at org.openqa.selenium.support.events.EventFiringWebDriver$$Lambda$315/1342232709.invoke(Unknown Source)
     at com.sun.proxy.$Proxy6.quit(Unknown Source)
     at org.openqa.selenium.support.events.EventFiringWebDriver.quit(EventFiringWebDriver.java:212)

问题描述

在Linux机器上运行Selenium Java应用,多次执行后进程出现挂起。线程转储显示java.io.PrintStream引发阻塞,该应用在Windows系统下运行正常,目前仅能通过重启进程解决问题。


核心原因

Linux与Windows的标准输出/错误流处理机制存在差异:Driver进程的输出流未被及时消费时,会触发PrintStream的锁竞争,导致执行quit操作的主线程和流泵线程相互阻塞,最终引发进程挂起。

可行解决方案

  • 自定义DriverService流处理
    替换默认的控制台输出,将Driver的日志重定向到文件或直接丢弃,避免锁竞争。示例代码:

    DriverService service = new FirefoxDriverService.Builder()
        .usingDriverExecutable(new File("path/to/geckodriver"))
        .usingAnyFreePort()
        .withStreamHandler(new PumpStreamHandler(new FileOutputStream("driver-output.log"), new FileOutputStream("driver-error.log")))
        .build();
    
  • 禁用Driver冗余日志
    通过系统属性关闭不必要的日志输出,减少流写入频率。以FirefoxDriver为例:

    System.setProperty(FirefoxDriver.SystemProperty.BROWSER_LOGFILE, "/dev/null");
    
  • 升级Selenium与Driver版本
    旧版本的Selenium或GeckoDriver存在Linux下的流处理bug,升级至最新稳定版(如Selenium 4.x系列)可修复此类问题。

  • 添加进程销毁钩子
    在应用中添加关机钩子,确保进程退出时强制清理Driver进程与关联流资源:

    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        if (driver != null) {
            driver.quit();
        }
    }));
    

内容的提问来源于stack exchange,提问作者Rajeshkumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 11:04:53