Pourquoi lsof sur OS X est-il si ridiculement lent?

36

Je n'arrive pas à comprendre pourquoi lsof sur mon Mac (10.8.2, MacBook Pro) est si lent.

Sur mon Mac, cela lsofprend plus d'une minute:

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

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

Sur une boîte Linux typique, exécutant Ubuntu 12.04, lsofprend 20 ms:

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

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

Le problème persiste si je lance lsof -n(pour éviter les recherches DNS). De plus, j'ai essayé de vérifier quels appels système sont effectués à l' lsofaide de dtruss, et j'ai constaté qu'il appelait des proc_infodizaines de milliers de fois:

$ 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

Des idées? J'ai exécuté ces tests et obtenu les mêmes résultats en utilisant à la fois la version lsofincluse avec OS X (4.85) ainsi que la dernière version de ftp://sunsite.ualberta.ca/pub/Mirror/lsof/ ( 4.87 ).

(Pour les curieux, la raison pour laquelle je suis frustré par ces performances est que lorsque je fais glisser des images vers Evernote, il s'exécute lsofen cours de copie du fichier, ce qui fait que mon système se bloque pendant une minute complète chaque fois que j'essaie d'insérer une image dans Evernote.)

Jason
la source
1
Si vous l'avez sorti sur la console au lieu d'un fichier, est-ce qu'il se bloque à un point particulier? Je suis également sur 10.8.2. Cela prenait 6 secondes pour moi, et j'ai remarqué qu'il se bloquait à chaque fois à mi-chemin de la liste des fichiers ouverts d'AirServer. J'ai tué AirServer et le temps est tombé à 1,76 s. Peut-être qu'il y a quelque chose sur votre système qui prend beaucoup de temps à évaluer?
Warren Pena
Point de données intéressant, @WarrenPena. Si je cours lsofsans argument (pour répertorier tous les fichiers), il se bloque pendant une minute puis imprime tous les fichiers. Mais, comme je l'ai mentionné, il se bloque toujours si j'essaie de répertorier qui a un seul fichier ouvert dans le répertoire / tmp, donc ce n'est pas un fichier ouvert particulier qui est le problème. De plus, je n'exécute aucun processus AirServer.
Jason
2
Cela (seulement?) Me prend environ une seconde. Vous pouvez également essayer sudo opensnoop -n lsof.
Lri
2
Cela me prend 19 s. Aucune idée pourquoi ...
daviewales
Bonne idée, @LauriRanta. J'ai essayé de courir sudo opensnoop -n lsofet lsof /tmp/testfiledans deux onglets, et opensnoop a seulement signalé que trois fichiers avaient été ouverts. Donc, le problème ne doit pas être un nombre excessif de fichiers ouverts, mais quelque chose lié à des proc_infoappels excessifs .
Jason

Réponses:

10

D'après mon expérience, de Mac OS X 10.7 (Lion) à 10.11.5 (EI Capitan), le lsoftoujours se bloquer.

Pour résoudre le problème, ajoutez l' -noption.

lsof -n

Selon le manuel de lsof, l' -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: S'il est encore lent, vous pouvez essayer

-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

La meilleure façon de découvrir pourquoi tant de lenteur est d'exécuter l'outil "Instruments" (à partir de l'icône de recherche Spotlight dans le coin supérieur droit) pour effectuer une "trace système" sur / usr / sbin / lsof, puis voir les appels graph et sys.

entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici

osexp2003
la source
2
Hou la la! Ajout de -ncouper mon lsof +Dbas de 5.31 realà 0.25 real. Cette option est pour ... réel
wetjosh
2
Encore ridiculement lent pour moi ...
Noldorin
Salut @Noldorin êtes-vous sur le même système d'exploitation que ce fil plus ancien? Si ce n'est pas le cas, une nouvelle question spécifique reliant ici votre configuration spécifique et votre calendrier spécifique pourrait valoir une nouvelle réponse.
bmike
3

Je pense que la plus grande partie du problème est que macOS devient de plus en plus ridicule avec des couches superflues et inutiles sur des couches de cadres inutiles. Cela signifie que des centaines de processus supplémentaires et des milliers de fichiers supplémentaires sont maintenus ouverts, ce qui augmente la quantité de travail lsofà faire d'au moins un ordre de grandeur, et peut-être plus comme deux ordres.

lsof est passé d'une vitesse raisonnable à une atrocement lente entre 10,6 et 10,13.

Ici, sur un système 10.13.4 actuel, je vois ce qui suit avec seulement 7 applications ouvertes et en cours d'exécution (Terminal, Chrome, Calendrier, Finder, Adium, IPGadget et Stickies). (Chrome a 7 fenêtres, avec peut-être 10 onglets chacune.)

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

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

Pendant l'exécution, les deux CPU dépassent largement 50% du temps système

L'ajout -Oaide parfois, surtout s'il lsofn'a pas été exécuté récemment, mais le meilleur que j'ai vu était d'environ 10% d'économies. Habituellement, il est minuscule et ne vaut probablement pas les risques décrits dans la page de manuel:

# time lsof -lnPO | wc -l
   10994

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

dtrussaffirme qu'il y a plus de 89 000 appels proc_info()avec ma charge de processus actuelle, et ceux-ci sont dans le noyau, et comme timerapports, la grande majorité du temps passé est dans le noyau. Je ne sais pas pourquoi il y a environ 8 appels par fichier ouvert.

Malheureusement, macOS / Darwin n'inclut pas la fstatcommande BSD toujours plus utile et efficace .

Greg A. Woods
la source
1

Je n'ai pas une bonne réponse pourquoi votre système semble prendre une minute de plus que mon Mac le plus lent pour appeler proc_info30 mille fois, mais votre timing montre que Linux et OS X sont dans la plage de 10 ms pour le temps utilisateur pour exécuter lsof. Pouvez-vous reproduire ce démarrage lent en mode sans échec pour exclure d'autres charges sur votre processeur?

J'ai essayé trois Mac et ceux exécutant 10.7.5 sont environ une seconde plus rapides que mon Mac 10.8.2. Les anciens systèmes d'exploitation sont des processeurs Core 2 Duo plus lents et je pense qu'un Mac i7 exécutant le nouveau système d'exploitation serait aussi rapide ou plus rapide que les anciens systèmes d'exploitation et CPU, mais je me trompe.

Toutes les machines font à peu près le même nombre d'appels proc_info, et toutes les machines ont un temps utilisateur maigre pour la commande - mais vous pourriez être sur un timing global plus lent (et je n'ai aucune idée pourquoi le vôtre est si dramatiquement plus lent que mon Mountain Lion Mac).

11 pouces Air (i7) 2011 exécutant 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 

MacBook Pro 15 pouces exécutant 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

IMac 27 pouces exécutant 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
bmike
la source
1
+1. J'utilise 10.8.2 sur un MBP fin 2010 (i7 + 8 Go), et pendant l'exécution d'un tas d'applications, j'obtiens ~ 1,8 s.
Harv