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:
- 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!
- 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).
- "sort -r -n" sorts numerically in reverse order (largest number at top)
- "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.