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

36

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

Auf meinem Mac lsofdauert es länger als eine Minute:

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

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

Auf einer typischen Linux-Box, auf der Ubuntu 12.04 ausgeführt wird, lsofdauert es 20 ms:

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

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

Das Problem besteht weiterhin, wenn ich ausgeführt werde lsof -n(um DNS-Lookups zu vermeiden). Außerdem habe ich versucht zu überprüfen, welche Systemaufrufe lsofmithilfe von ausgeführt werden 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 lsofmit der in OS X enthaltenen Version ( 4.85 ) als auch mit der neuesten Version von ftp://sunsite.ualberta.ca/pub/Mirror/lsof/ ( 4.87 ) erzielt .

(Für die Neugierigen ist der Grund, warum ich von dieser Leistung frustriert bin, der, dass wenn ich Bilder auf Evernote ziehe, diese lsofbeim Kopieren der Datei ausgeführt werden und mein System jedes Mal, wenn ich versuche, ein Bild einzufügen, für eine volle Minute hängen bleibt in Evernote.)

Jason
quelle
1
Wenn Sie es anstelle einer Datei auf der Konsole ausgeben lassen, hängt es dann an einer bestimmten Stelle? Ich bin auch am 10.8.2. Es dauerte 6 Sekunden und ich bemerkte, dass es jedes Mal nach der Hälfte der Auflistung der geöffneten Dateien von AirServer hängen blieb. Ich habe AirServer getötet und die Zeit ist auf 1,76 Sekunden gesunken. Vielleicht gibt es etwas auf Ihrem System, dessen Evaluierung lange dauert?
Warren Pena
Interessanter Datenpunkt, @WarrenPena. Wenn ich lsofohne Argumente ausführe (um alle Dateien aufzulisten), bleibt es eine Minute lang hängen 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 Verzeichnis / tmp geöffnet hat. Es handelt sich also nicht um eine bestimmte geöffnete Datei, die das Problem darstellt. Außerdem führe ich keinen AirServer-Prozess aus.
Jason
2
Es dauert (nur?) Ungefähr eine Sekunde für mich. Sie könnten es auch versuchen sudo opensnoop -n lsof.
Lri
2
Es dauert 19 s für mich. Keine Ahnung warum ...
Daviewales
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 darf also nicht darin bestehen, dass zu viele Dateien geöffnet werden, sondern in Bezug auf zu viele proc_infoAufrufe.
Jason

Antworten:

10

Nach meiner Erfahrung, von Mac OS X 10.7 (Lion) bis 10.11.5 (EI Capitan), bleibt das lsofimmer hängen.

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

lsof -n

Nach Anleitung 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

BEARBEITEN 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

Die ultimative Möglichkeit, herauszufinden, warum dies so langsam ist, besteht darin, das Tool "Instruments" (in der oberen rechten Ecke des Spotlight-Suchsymbols) auszuführen, um eine "Systemablaufverfolgung" für / usr / sbin / lsof durchzuführen und dann die Aufrufe von graph und sys anzuzeigen.

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

osexp2003
quelle
2
Wow! Füge -nmeinen Schnitt lsof +Dvon 5.31 realbis hinzu 0.25 real. Diese Option ist für ... real
wetjosh
2
Immer noch lächerlich langsam für mich ...
Noldorin
Hallo @Noldorin, bist du im selben Betriebssystem wie dieser ältere Thread? Wenn nicht, ist eine neue spezifische Frage, die hier mit Ihrem spezifischen Setup und Ihrem spezifischen Timing verknüpft ist, möglicherweise eine neue Antwort wert.
bmike
3

Ich denke, der größte Teil des Problems ist, dass macOS immer lächerlicher wird, wenn es überflüssige und unnötige Schichten verschwenderischer Frameworks gibt. Dies hat dazu geführt, dass Hunderte von zusätzlichen Prozessen und Tausende von zusätzlichen Dateien geöffnet wurden, wodurch sich der Arbeitsaufwand lsofum mindestens eine Größenordnung und möglicherweise sogar um zwei Größenordnungen erhöhte .

lsof ging von angemessener Geschwindigkeit auf schrecklich langsam zwischen 10.6 und 10.13.

Hier sehe ich auf einem aktuellen 10.13.4-System das Folgende mit nur 7 geöffneten und laufenden Apps (Terminal, Chrome, Kalender, Finder, Adium, IPGadget und Stickies). (Chrome verfügt über 7 Fenster mit jeweils 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 weit über 50% der 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 die in der Handbuchseite beschriebenen Risiken wahrscheinlich nicht wert:

# time lsof -lnPO | wc -l
   10994

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

dtrussbehauptet, es gibt über 89.000 Anrufe proc_info()mit meiner aktuellen Prozesslast, und diese gehen in den Kernel, und wie es heißt time, ist die überwiegende Mehrheit der aufgewendeten Zeit im Kernel. Ich weiß nicht, warum es ungefähr 8 Aufrufe pro geöffneter Datei gibt.

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

Greg A. Woods
quelle
1

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

Ich habe drei Macs ausprobiert und diejenigen, auf denen 10.7.5 ausgeführt wird, sind ungefähr eine Sekunde schneller als mein 10.8.2-Mac. Das ältere Betriebssystem ist ein langsamerer Core 2 Duo-Prozessor, und ich denke, ein i7-Mac mit dem neueren Betriebssystem ist genauso schnell oder schneller als ein älteres Betriebssystem und eine ältere CPU, aber ich würde mich irren.

Alle Maschinen führen ungefähr die gleiche Anzahl von proc_info-Aufrufen durch, und alle Maschinen verfügen über eine geringe Benutzerzeit für den Befehl. Möglicherweise haben Sie jedoch ein langsameres Timing (und ich habe keine Ahnung, warum Ihr System 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 - Festplatte:

$ 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 - Festplatte:

$ 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
bmike
quelle
1
+1. Ich verwende 10.8.2 auf einem MBP von Ende 2010 (i7 + 8GB), und während ich eine Reihe von Apps verwende, bekomme ich ~ 1.8s.
Harv