天天看點

java.io.FileNotFoundException: open failed: EMFILE (Too many open files)

java.io.FileNotFoundException: open failed: EMFILE (Too many open files)

出現這個問題是由于目前進度打開的檔案數超出系統的最高限度,核心不再讓其打開檔案了。是以再打開任何檔案就是失敗的。

檢視目前檔案打開了哪些檔案,使用lsof -p 本程序ID 可以檢視到目前進度打開了哪些檔案。我的問題是不停的打開/dev/bus/usb目錄下的檔案,但是并沒有關閉,導緻出現了這個問題。

上面的話對應到程式中是這樣的:

int fd = open("/hello", O_RDONLY) 

sleep(); // 檢視到是打開了hello的

close(fd);

sleep(); // 檢視不到打開hello檔案 

return;

           // 檢視不到。
           

完整測試程式:

#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <unistd.h>

#define DEV "/dev/usb/lp0"

int main(void) {
    int fd;
    int pid = (int) getpid ();
    fd = open(DEV, O_RDONLY);
    if(fd < ) {
        perror("open DEV");
        return ;
    }
    printf("open file.... pid=%d\n", pid);
    sleep(); // 這裡使用lsof -p $pid檢視

    close(fd);
    printf("close file....pid=%d\n", pid);
    sleep(); // 這裡使用lsof -p $pid檢視

    puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
    return EXIT_SUCCESS;
}
           

一般情況下,打開檔案使用後會立即關閉是正常流程,如果打開了沒有關閉,調試程式的時候可以檢測不出問題,但是如果是程式運作到目标機器上連續運作幾天就可能出現問題了,因為這個是有臨界值的,如果你這個程序打開的檔案過多,那麼系統就不讓你再打開檔案了,這樣就會造成你程式不能正常工作了,BUG往往來源于小錯。

這種錯誤要歸類到軟體釋出前必然檢察項了,這就好比一個新電路闆焊接好,上電測試前要做的準備檢測一樣。雖然不能保證整個電路都是正常的,但是至少用萬用表測試一下電路闆電源是否短路一樣的簡單而非常必要。

總之當核心禁止你打開任何的新檔案,在Android中會遇到各種問題同樣也會有:

E/(3193): BitTube(Parcel): can’t dup filedescriptor (Bad file number)