int AbstractFile::OpenFile(const char* pathName, int oflag, mode_t mode){ m_fileID = open(pathName, oflag, mode); if (m_fileID == -1) { m_fileID = 0; // error message
perror("###########OPEN FILE Error,msg:"); return ERROR_OPEN_FILE; } return m_fileID;}
---一下就定位出來出錯的原因: too many open file
然後根據此文章
http://langyu.javaeye.com/blog/763247
詳解 Too many open files
文章分類:作業系統
運行在Linux系統上的Java程式可能會出現"Too many open files"的異常情況,且常見於高並發訪問檔案系統,多線程網路連接等情境。
程式經常訪問的檔案、socket在Linux中都是檔案file,系統需要記錄每個當前訪問file的name、location、access authority等相關資訊,這樣的一個實體被稱為file entry。“open files table”(圖中橙色標識)儲存這些file entry,以數組的形式線性管理。檔案描述符(file descriptor)作為進程到open files table的指標,也就是open files table的下標索引,將每個進程與它所訪問的檔案關聯起來了。
每個進程中都有一個file descriptor table管理當前進程所訪問(open or create)的所有檔案,檔案描述符關聯著open files table中檔案的file entry。細節不表,對於open files table能容納多少file entry。Linux系統配置open files table的檔案限制,如果超過配置值,就會拒絕其它檔案操作的請求,並拋出Too many open files異常。這種限制有系統級和使用者級之分。
系統級:
系統級設定對所有使用者有效。可通過兩種方式查看系統最大檔案限制
1 cat /proc/sys/fs/file-max
2 sysctl -a 查看結果中fs.file-max這項的配置數量
如果需要增加配置數量就修改/etc/sysctl.conf檔案,配置fs.file-max屬性,如果屬性不存在就添加。
配置完成後使用sysctl -p來通知系統啟用這項配置
使用者級:
Linux限制每個登入使用者的可串連檔案數。可通過 ulimit -n來查看當前有效設定。如果想修改這個值就使用 ulimit -n <setting number> 命令。
對於檔案描述符增加的比例,資料推薦是以2的冪次為參考。如當前檔案描述符數量是1024,可增加到2048,如果不夠,可設定到4096,依此類推。
在出現Too many open files問題後,首先得找出主要原因。最大的可能是開啟的檔案或是socket沒有正常關閉。為了定位問題是否由Java進程引起,通過Java進程號查看當前進程佔用檔案描述符情況: Java代碼
- lsof -p $java_pid 每個檔案描述符的具體屬性
- lsof -p $java_pid | wc -l 當前Java進程file descriptor table中FD的總量
分析命令的結果,可判斷問題是否由非正常釋放資源所引起。
我通過命令獲得使用者層級的話,是1024個檔案。然後採用ps -d 獲得dataManage這個進程的id號比如是3626,lsof -p 3626|more來查看它操作了哪些檔案。lsof -p 3626|wc -l 來統計其操作的檔案的個數。發現有一個很特殊的檔案叫 (null)/MemInfo.txt在不斷的增長,果然,當它增長到1024的時,插入圖片就出錯了。之後也不再進行圖片資料的操作。
原因就在這裡了,那:為什麼會產生MemInfo.txt這個空檔案呢???
而且 MemInfo.txt 其完整路徑是 (null)\MemInfo.txt,這是一個空路徑,我無法在代碼裡面找到關於它的任何資訊。用find path filename 也找不到檔案。
於是懷疑是調用的lib庫產生問題,採用如下命令
/usr/lib
然後使用 /usr/lib/ |xargs grep MemInfo.txt
提示: Binary file /usr/lib/libGGG_HR_PR.so matches
ok,只需要調用lib對應的測試程式,就可以校正是不是那個問題了。