您好我有一些使用块
的代码RandomAccessFile file = new RandomAccessFile("some file", "rw");
FileChannel channel = file.getChannel();
// some code
String line = "some data";
ByteBuffer buf = ByteBuffer.wrap(line.getBytes());
channel.write(buf);
channel.close();
file.close();
但应用程序的具体内容是我必须生成大量临时文件,平均超过4000个(用于将Hive插入到分区表中)。
问题是我有时会遇到异常
Failed with exception Too many open files
在应用运行期间。
我是否有任何方法告诉操作系统文件已经关闭并且不再使用,为什么
channel.close();
file.close();
不会减少已打开文件的数量。有没有办法在Java代码中执行此操作?
我已经增加了
中已打开文件的最大数量#/etc/sysctl.conf:
kern.maxfiles=204800
kern.maxfilesperproc=200000
kern.ipc.somaxconn=8096
更新 我试图消除这个问题,所以我将代码分开来调查它的每个部分(创建文件,上传到配置单元,删除文件)。
使用“File”或“RandomAccessFile”类失败,但“打开的文件太多”除外。
最后我使用了代码:
FileOutputStream s = null;
FileChannel c = null;
try {
s = new FileOutputStream(filePath);
c = s.getChannel();
// do writes
c.write("some data");
c.force(true);
s.getFD().sync();
} catch (IOException e) {
// handle exception
} finally {
if (c != null)
c.close();
if (s != null)
s.close();
}
这适用于大量文件(在20K上测试,每个文件大小为5KB)。代码本身不会像以前的两个类那样抛出异常。 但是生产代码(带有配置单元)仍然有例外。而且似乎通过JDBC的hive连接就是它的原因。 我会进一步调查。
答案 0 :(得分:4)
操作系统可以使用的打开文件句柄数量与进程可以打开的文件句柄数量不同。大多数unix系统限制每个进程的文件句柄数。最有可能是你的JVM的1024个文件句柄。
a)您需要在启动JVM的shell中设置ulimit到更高的值。 (比如'ulimit -n 4000')
b)您应该验证您没有任何资源泄漏阻止您的文件“最终确定”。
答案 1 :(得分:3)
确保使用finally {}块。如果由于某种原因存在异常,则代码中的关闭将永远不会发生。
答案 2 :(得分:0)
这是确切的代码吗?因为我可以想到一个场景,你可能会在循环中打开所有文件并编写代码以最终关闭所有这些文件,这导致了这个问题。请发布完整的代码。