当出现 Too many open files
异常的时候,意味着文件句柄泄漏过多,句柄泄漏到一定数量之后(一般是接近1024)会导致程序卡死、文件读写异常、socket创建异常等。
一般来说单一进程的最大可打开文件句柄数量为1024
,可通过cat proc/进程ID/limits
查看。
java代码查询最大句柄数量
public static int getMaxOpenFiles() {
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile("/proc/" + Process.myPid() + "/limits", "r");
String line;
while ((line = randomAccessFile.readLine()) != null) {
if (line.contains("Max open files")) {
line = line.replace("Max open files", "")
.replace("files", "").trim();
String[] split = line.split(" ");
for (String item : split) {
if (!TextUtils.isEmpty(item)) {
randomAccessFile.close();
randomAccessFile = null;
return Integer.parseInt(item);
}
}
}
}
} catch (Exception e) {
Log.w(TAG, e);
} finally {
if(randomAccessFile != null){
randomAccessFile.close();
randomAccessFile = null;
}
}
return 0;
}
当前程序已使用的句柄数量可进入文件夹 cd proc/进程ID/fd
查看
当前文件句柄数量为
fd
目录下文件总数量,图中有88个打开的文件句柄
java代码查询当前句柄数量
public static int getFdCount() {
File fdFile = new File("/proc/" + Process.myPid() + "/fd");
File[] files = fdFile.listFiles();
return null == files ? 0 : files.length;
}
在Android
中能造成文件句柄泄漏主要有以下三类
1、Process
Process process = Runtime.getRuntime().exec("getprop ");
...
process.destroy();
Process
使用完之后一定要调用 destroy()
2、各种Stream
InputStream
OutputStream
ByteArrayOutputStream
ByteArrayInputStream
DataOutputStream
DataInputStream
InputStreamReader
OutputStreamWriter
BufferedInputStream
BufferedOutputStream
FileInputStream
FileOutputStream
ZipOutputStream
ZipInputStream
FileReader
FileWriter
BufferedReader
BufferedWriter
RandomAccessFile
LineNumberReader
这些用完之后一定要记得close()
,养成良好的编码习惯
3、Socket
很多时候句柄泄漏是socket
不能正确的关闭导致的,所以在停止业务的时候,要保证socket
都能正确的关闭
通过 slof -p 进程ID
可查看当前进程的句柄情况
大致可以定位句柄泄漏的类型
网友评论