Determine which app is opening too many files

Solution 1:

Time to bring the power of Unix pipes, sort, and awk to the rescue. But since lsof takes a long time to run I'll save the output and analyze that, rather than piping lsof directly into the pipe.

For reference here's the lsof output format:

[iMac:~] droot% head /tmp/a
COMMAND    PID  USER   FD      TYPE             DEVICE   SIZE/OFF     NODE NAME
loginwind   94 droot  cwd       DIR                1,7        896        2 /
loginwind   94 droot  txt       REG                1,7    1237152 18011104 /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow
loginwind   94 droot  txt       REG                1,7      21024 18566026 /Library/Preferences/Logging/.plist-cache.HrVraTtH
loginwind   94 droot  txt       REG                1,7   27154336 18044520 /usr/share/icu/icudt62l.dat

And my analysis:

lsof > /tmp/a
cat /tmp/a | awk '{print $2}' | sort | uniq -c | sort -r -n | head

 511 724
 469 2790
 384 2791
 360 2793
 350 2798
 227 286
 224 658
 210 3833
 197 655
 190 698

Explaining the non-obvious lines:

  1. awk '{print $2}' prints the 2nd field in each line (the PID in this case). This is about all the awk I remember. Really useful!
  2. uniq -c Takes a sorted list of PIDs and eliminates duplicate adjacent lines, with the -c modifier it adds a count of the number of lines found (in our case that's one line per open file from that process).
  3. "sort -r -n" sorts numerically in reverse order (largest number at top)
  4. "head" prints out the first 10 lines (10 processes with largest number of open files).

That shows that PID 724 has 511 open files on my system. To look in more detail:

cat /tmp/a | grep " 724 "

In my case that process was Dropbox, which is "interesting" but I can see that that process might need many open files. So going to the next one:

cat /tmp/a | grep " 2790 "

And so on down the list. Hopefully your "offender" is obvious from the lsof output sorted by number of open files per PID.

For total number of open files use "wc" (wordcount):

[iMac:~] droot% cat /tmp/a | wc
9777   90500 1445558

Which means 9776 open files in my case (have to subtract the header line).

Solution 2:

Did you tried:

lsof -n | awk '{print $1}' | uniq -c | sort -rn | head -n $LINES

It should print a list of processes sorted by the number of open files

Solution 3:

I just found the Sloth app. It is basically a GUI for lsof, and is able to group and sort processes by file count, which is exactly what I need. About the only thing I could ask for that is missing was a tally of the total number of open files in the system.