2011-05-24 64 views
5

您好我有一个使用一些代码块减少打开的文件数在Java代码中

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 

应用程序运行过程中。

我wounder如果有任何的方式来告诉操作系统,文件被关闭已经不使用了,为什么

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(); 
} 

而且这个作品用大量的文件(每个5KB大小的20K测试)。代码本身不会像前两个类一样抛出异常。 但生产代码(与配置单元)仍然有例外。看起来,通过JDBC的配置单元连接是其原因。 我会进一步调查。

+0

听起来像是依靠终结者关闭外部资源。那是......真的在找麻烦。 – 2011-05-24 15:33:01

回答

4

操作系统可以使用的打开文件句柄的数量与流程可以打开的文件句柄的数量不同。大多数Unix系统限制每个进程的文件句柄数量。很可能它就像您的JVM的1024个文件句柄。

a)您需要在启动JVM的shell中将ulimit设置为更高的值。 (类似于'ulimit -n 4000')

b)您应该验证您没有任何资源泄漏阻止您的文件被“终结”。

0

这是确切的代码?因为我可以考虑一个场景,您可能会打开循环中的所有文件,并编写代码以最终关闭所有文件,从而导致此问题。请发布完整的代码。

+0

使用模式如下:1)从mysql源获取数据到一些数据对象2)循环对象列表并在每次迭代中执行发布的代码。因此,我在每次迭代中都会发布代码并且没有打开所有文件。 – ykhrustalev 2011-05-24 15:53:45

3

确保使用finally {}块。如果由于某种原因存在异常,那么封闭将永远不会发生在代码中。