Warum ist lsof unter OS X so lächerlich langsam?

Ich kann nicht herausfinden, warum lsof auf meinem Mac (10.8.2, MacBook Pro) so langsam ist.

Dauert auf meinem Mac lsofmehr als eine Minute:

$ touch /tmp/testfile
$ time lsof /tmp/testfile

real   1m16.483s
user   0m0.029s
sys    1m15.969s

Auf einer typischen Linux-Box mit Ubuntu 12.04 lsofdauert es 20 ms:

$ touch /tmp/testfile
$ time lsof /tmp/testfile

real   0m0.023s
user   0m0.008s
sys    0m0.012s

Das Problem bleibt bestehen, wenn ich es ausführe lsof -n(um DNS-Lookups zu vermeiden). Außerdem habe ich versucht zu überprüfen, welche Systemaufrufe mit durchgeführt lsofwerden dtruss, und festgestellt, dass es proc_infoZehntausende Male aufruft:

$ sudo dtruss lsof /tmp/testfile 2> /tmp/dump
$ cat /tmp/dump | sort | uniq -c | sort -nr | head
10000 proc_info(0x2, 0x1199, 0x8) = 1272 0
 6876 proc_info(0x2, 0x45, 0x8) = 1272 0
 2360 proc_info(0x2, 0x190D, 0x8) = 1272 0
 1294 proc_info(0x2, 0xFF, 0x8) = 1272 0
 1152 proc_info(0x2, 0x474, 0x8) = 1272 0
 1079 proc_info(0x2, 0x2F, 0x8) = 1272 0
  709 proc_info(0x2, 0xFE, 0x8) = 1272 0
  693 proc_info(0x2, 0x1F, 0x8) = 1272 0
  623 proc_info(0x2, 0x11A, 0x8) = 1272 0
  528 proc_info(0x2, 0xF7, 0x8) = 1272 0

Irgendwelche Ideen? Ich habe diese Tests durchgeführt und die gleichen Ergebnisse sowohl mit der Version von lsofOS X (4.85) als auch mit der neuesten Version von ftp://sunsite.ualberta.ca/pub/Mirror/lsof/ (4.87) erhalten.

(Für die Neugierigen, der Grund, warum ich von dieser Leistung frustriert bin, ist, dass, wenn ich Bilder auf Evernote ziehe, es während lsofdes Kopierens der Datei läuft, was dazu führt, dass mein System jedes Mal, wenn ich versuche, ein Bild einzufügen, eine volle Minute lang hängen bleibt bei Evernote.)

Wenn Sie es anstelle einer Datei auf der Konsole ausgeben lassen, hängt es an einem bestimmten Punkt? Ich bin auch am 10.8.2. Es dauerte 6 Sekunden für mich, und ich bemerkte, dass es jedes Mal auf der Hälfte der Liste der geöffneten Dateien von AirServer hängen blieb. Ich habe AirServer getötet und die Zeit ist auf 1,76 s gesunken. Vielleicht gibt es etwas auf Ihrem System, dessen Auswertung viel Zeit in Anspruch nimmt?
Interessanter Datenpunkt, @WarrenPena. Wenn ich lsofohne Argumente laufe (um alle Dateien aufzulisten), hängt es eine Minute lang und druckt dann alle Dateien. Aber wie ich bereits erwähnt habe, hängt es immer noch, wenn ich versuche aufzulisten, wer eine einzelne Datei im /tmp-Verzeichnis geöffnet hat, also ist es nicht eine bestimmte offene Datei, die das Problem ist. Außerdem führe ich keinen AirServer-Prozess aus.
Bei mir dauert es (nur?) etwa eine Sekunde. Du könntest es auch versuchen sudo opensnoop -n lsof.
Bei mir dauert es 19 s. Keine Ahnung warum...
Gute Idee, @LauriRanta. Ich habe versucht, sudo opensnoop -n lsofund lsof /tmp/testfilein zwei Registerkarten auszuführen, und opensnoop hat nur gemeldet, dass drei Dateien geöffnet wurden. Das Problem muss also nicht an einer übermäßigen Anzahl von Dateiöffnungen liegen, sondern an übermäßigen proc_infoAufrufen.
Bemerken Sie eine andere Langsamkeit auf der Maschine? Ich sehe, lsofdass Mountain Lion eine Sekunde langsamer ist als Lion, also sind offensichtlich einige Änderungen im Gange (vielleicht optimieren sie für andere Anrufe oder leisten deutlich mehr Arbeit mit GateKeeper oder Code Signing).
Ich habe festgestellt, dass lsof mehrere Minuten dauern kann, wenn ein Prozess einen sehr großen virtuellen Adressraum hat. Beachten Sie, dass der virtuelle Adressraum viel größer sein kann als der tatsächlich verwendete Speicher. Ich habe das gesehen, als vsize von 60G .. 11T war.
~25 Sek hier mit einem 2 GhZ MBP am 10.9. Ich denke, dass die Implementierung jede PID durchläuft und alle ihre offenen FDs abfragt.
real 4m27.515s Benutzer 0m0.263s sys 0m7.311s
20s für mich, mit einem 2012 MBP am 13.10.4.

Antworten (3)

Wie meine Erfahrung von Mac OS X 10.7 (Lion) bis 10.11.5 (EI Capitan) lsofhängt das immer.

Um das Problem zu lösen, fügen Sie die -nOption an.

lsof -n

Laut Handbuch von lsof, die -nOption:

inhibits the conversion of network numbers to host names for network files.  
Inhibiting conversion may make  lsof  run faster.  It is also useful when host 
name lookup is not working properly

EDIT 2018-04-25: Wenn es immer noch langsam ist, können Sie es versuchen

-O to bypass  the  strategy it uses to avoid being blocked by some kernel operations
-P to inhibits the conversion of port numbers to port names for network files
-l to inhibits  the  conversion of user ID numbers to login names

Der ultimative Weg, um herauszufinden, warum es so langsam ist, besteht darin, das „Instruments“-Tool (über das Spotlight-Suchsymbol in der oberen rechten Ecke) auszuführen, um einen „System Trace“ auf /usr/sbin/lsof durchzuführen und dann Diagramm- und Systemaufrufe anzuzeigen.

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Wow! Hinzufügen von -ncut my lsof +Ddown from 5.31 realto 0.25 real. Diese Option ist echt
Immer noch lächerlich langsam für mich ...
Hallo @Noldorin, bist du auf demselben Betriebssystem wie dieser ältere Thread? Wenn nicht, könnte eine neue spezifische Frage, die hier mit Ihrer spezifischen Einrichtung und Ihrem spezifischen Timing verknüpft ist, eine neue Antwort wert sein.

Ich denke, der größte Teil des Problems besteht darin, dass macOS immer lächerlicher wird mit aufgeblähten und unnötigen Schichten von verschwenderischen Frameworks. Dies hat dazu geführt, dass Hunderte von zusätzlichen Prozessen und Tausende von zusätzlichen Dateien offen gehalten werden, was den Arbeitsaufwand lsofum mindestens eine Größenordnung und vielleicht eher um zwei Größenordnungen erhöht.

lsofging zwischen 10.6 und 10.13 von angemessener Geschwindigkeit zu schrecklich langsam.

Hier auf einem aktuellen 10.13.4-System sehe ich Folgendes mit nur 7 geöffneten und laufenden Apps (Terminal, Chrome, Kalender, Finder, Adium, IPGadget und Stickies). (Chrome hat 7 Fenster mit jeweils vielleicht 10 Registerkarten.)

# ps ax | wc -l
     401
# time lsof -lnP | wc -l
   10976

real    0m49.684s
user    0m0.250s
sys 0m40.172s

Während des Laufs sind beide CPUs deutlich über 50% Systemzeit

Das Hinzufügen -Ohilft manchmal, besonders wenn lsofes in letzter Zeit nicht ausgeführt wurde, aber das Beste, was ich gesehen habe, waren etwa 10 % Einsparungen. Normalerweise ist es winzig und wahrscheinlich die in der Handbuchseite beschriebenen Risiken nicht wert:

# time lsof -lnPO | wc -l
   10994

real    0m47.482s
user    0m0.249s
sys 0m40.472s

dtrussbehauptet, dass es proc_info()bei meiner aktuellen Prozesslast über 89.000 Aufrufe gibt, und diese befinden sich im Kernel, und timeBerichten zufolge wird die überwiegende Mehrheit der Zeit im Kernel verbracht. Ich weiß nicht, warum es ungefähr 8 Aufrufe pro geöffneter Datei gibt.

Leider enthält macOS/Darwin nicht den immer nützlicheren und effizienteren BSD- fstatBefehl.

Ich habe keine gute Antwort darauf, warum Ihr System anscheinend eine Minute länger braucht als mein langsamster Mac, um proc_info30.000 Mal anzurufen, aber Ihr Timing zeigt, dass sowohl Linux als auch OS X im Bereich von 10 ms liegen, damit die Benutzer lsof ausführen können. Können Sie diese langsame Zeit beim Booten im abgesicherten Modus reproduzieren, um andere Lasten auf Ihrer CPU auszuschließen?

Ich habe drei Macs ausprobiert und die mit 10.7.5 sind etwa eine Sekunde schneller als mein 10.8.2-Mac. Die älteren Betriebssysteme sind langsamere Core 2 Duo-Prozessoren, und ich würde denken, dass ein i7-Mac mit dem neueren Betriebssystem genauso schnell oder schneller ist als ältere Betriebssysteme und CPUs, aber ich würde mich irren.

Alle Maschinen machen ungefähr die gleiche Anzahl von proc_info-Aufrufen, und alle Maschinen haben wenig Benutzerzeit für den Befehl - aber Sie haben möglicherweise ein langsameres Gesamttiming (und ich habe keine Ahnung, warum Ihre so dramatisch langsamer ist als mein Mountain Lion Mac).

11 Zoll Air (i7) 2011 mit Mountain Lion - SSD:

$ system_profiler SPSoftwareDataType
      System Version: OS X 10.8.2 (or something)
      Kernel Version: Darwin 12.3.0
      Secure Virtual Memory: Enabled
$ time lsof /tmp/testfile 

real    0m1.179s
user    0m0.012s
sys     0m1.158s
$ sudo dtruss lsof /tmp/testfile 2> /tmp/dump
$ cat /tmp/dump | sort | uniq -c | sort -nr | head
9310 proc_info(0x2, 0x68, 0x8)           = 1272 0
1220 proc_info(0x2, 0xCEB6, 0x8)                 = 1272 0
$ cat /tmp/dump | cut -c -9 | sort | uniq -c | sort -nr | head
30884 proc_info
 116 write(0x4
  87 read(0x5,
  60 sigaction
  60 setitimer
  35 stat64("/
  30 sigprocma
  30 sigaltsta
  21 close(0x3
  18 close(0x6 

15 Zoll MacBook Pro mit Lion Server – HDD:

$ system_profiler SPSoftwareDataType
      System Version: Mac OS X Server 10.7.5 (11G63)
      Kernel Version: Darwin 11.4.2
$ time lsof /tmp/testfile

real    0m0.329s
user    0m0.005s
sys     0m0.324s

27 Zoll iMac mit Lion - HDD:

$ system_profiler SPSoftwareDataType
      System Version: Mac OS X 10.7.5 (11G63b)
      Kernel Version: Darwin 11.4.2
$ time lsof /tmp/testfile

real    0m0.066s
user    0m0.002s
sys     0m0.065s
$ sudo dtruss lsof /tmp/testfile 2> /tmp/dump
$ cat /tmp/dump | cut -c -9 | sort | uniq -c | sort -nr | head
23034 proc_info
 188 write(0x4
 141 read(0x5,
  96 sigaction
  96 setitimer
  48 sigprocma
  48 sigaltsta
  31 stat64("/
  21 close(0x3
  18 close(0x6
+1. Ich verwende 10.8.2 auf einem MBP von Ende 2010 (i7 + 8 GB), und während ich eine Reihe von Apps ausführe, erhalte ich ~ 1,8 Sekunden.