我查看了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/