too many open files

最近在工作遇到一个问题,too many open files异常,这个异常最终的结果导致Resin停止响应。
在我们的系统中是发现把一个目录当作文件来读取,而JDK1.4对这种情况虽然抛出了异常,但是已经打开的文件句柄没有及时的释放,最终超出了系统的限制,在Linxu下,可以用ulimit -a查看每个进程允许打开的文件个数,我们的是1024.

下面的代码解释了这种问题的发生,运行环境:JDK1.4
import java.io.*;
public class TestFile
{
public static void main(String[] args) throws Exception{
read("/opt/");
Thread.sleep(10000);
}
public static String read( String file )
{
String ret = null;

File f = null;
BufferedInputStream result = null;
ByteArrayOutputStream baos = null;

try{
f = new File( file );
if(!f.exists())
{
System.out.println("file:"+file+" does not exist");
return ret;
}
/*
在这里加上对是否是文件的判断
else if(!f.isFile()){
return null;
}
*/
result = new BufferedInputStream( new FileInputStream(f) );//这里会抛出异常
baos = new ByteArrayOutputStream();
.........
ret = new String(baos.toByteArray());
}catch(Exception e){
e.printStackTrace();
}finally {
try
{
if( result!=null ) result.close();
if( baos!=null ) baos.close();
f = null;
}catch(Exception e) {
e.printStackTrace();
}
}
return ret;
}
}

执行java TestFile之后,在线程等待的时候,用lsof -p 查看该java进程所打开的文件句柄,得到类似下面的结果:
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
java 7535 agile cwd DIR 8,1 4096 326402 /opt

可以看到,虽然读取/opt的时候会有异常抛出,但是文件的句柄并没有被释放,累积的结果就是too many open files.

刚才在jdk 1.5上做了测试,这个问题已经解决了,它的提示更友好:
java.io.FileNotFoundException: /opt (Is a directory)
而用lsof -p 查看的时候也没有发现有"/opt"

建议在jdk1.4上做开发的朋友,在读文件的时候一定要多加小心。
posted @ 2011-12-22 09:38  规格严格-功夫到家  阅读(854)  评论(0编辑  收藏  举报