java - JDK 1.7 : "Too many open files" due to POSIX Semaphores?

标签 java file-io java-7

我查看了SO上的其他类似问题,但它们似乎是由其他问题引起的。

首先,我确保明智地关闭了所有文件句柄,然后我使用了 lsof -p <pid of java> 查看我的文件列表。

它在我的整个运行期间保持相当稳定,但之后我会定期获得 lsof 中列出的大约 10,000 个条目像这样:

COMMAND   PID USER   FD     TYPE DEVICE  SIZE/OFF     NODE NAME
                                      ...
java    36809  smm *235r  PSXSEM              0t0          kcms00008FC901624000
java    36809  smm *236r  PSXSEM              0t0          kcms00008FC901624000
java    36809  smm *237r  PSXSEM              0t0          kcms00008FC901624000
java    36809  smm *238r  PSXSEM              0t0          kcms00008FC901624000
java    36809  smm *239r  PSXSEM              0t0          kcms00008FC901624000

手册页说 PSXSEM类型是 POSIX 信号量。知道 JDK 使用 POSIX 信号量做什么吗?顺便说一句,该应用目前是单线程命令行应用。

可能有用的背景:我在 Mac OS X 10.7.3 上升级到 JDK 1.7 后首先注意到这一点:

java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)

更新:重新指向 $JAVA_HOME JDK 1.6 似乎是该问题的解决方法。

java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)

JDK 1.7 有何不同之处?

最佳答案

我能够追溯到这段代码:

BufferedImage image = null;
ImageInputStream stream = null;
try {
    stream = new FileImageInputStream(file);
    image = ImageIO.read(stream);

} catch (Exception ex) {
    log.error("Image could not be read: "+file.getPath());

} finally {
    // ImageIO closes input stream unless null is returned
    // http://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html#read(javax.imageio.stream.ImageInputStream)
    if (stream != null && image == null) {
        try {
            stream.close();
        } catch (IOException ex) {
            log.error("ERROR closing image input stream: "+ex.getMessage(), ex);
        }
    }
}

JavaDocs 特别指出此方法(与其他方法不同)会自动关闭流。事实上,当您尝试手动关闭它时,它会抛出一个异常提示“已关闭”。我正在使用这个重载,因为另一个人说它无论如何都将它包装在 ImageInputStream 中,所以我想我会节省一些工作。

更改 block 以使用普通的 FileInputStream 修复泄漏:

BufferedImage image = null;
InputStream stream = null;
try {
    stream = new FileInputStream(file);
    image = ImageIO.read(stream);

} catch (Exception ex) {
    log.error("Image could not be read: "+file);

} finally {
    if (stream != null) {
        try {
            stream.close();
        } catch (IOException ex) {
            log.error("ERROR closing image input stream: "+ex.getMessage(), ex);
        }
    }
}

在我看来,这是 JDK 1.7 中的一个错误,因为 1.6 在这里运行良好。

更新:我只是submitted a bug report向 Oracle 解决这个问题。

关于java - JDK 1.7 : "Too many open files" due to POSIX Semaphores?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10441276/

相关文章:

java - CloudFoundry 上的 MySql 经常因查询执行中断而失败;

java 8 javafx getBehavior() 替代方案?

java - java中两个线程同步访问HashMap

c - 是否可以将标准输入/输出设置为 C 中的文件?

Java 10 : Will Java 7's Diamond Inference Work with Local Type Inference?

java - Android Studio/Java/XML 中的 "Unbound Prefix"是什么?

c - 这是正确的吗? (在 C 中读入文件)

c++ - Windows 系统中是否存在未缓冲的 I/O?

java - 为什么 try-with-resources 不能与字段变量一起使用?

Java - 在中间或除双端队列前端/末尾以外的任何位置插入元素