Por que o lsof no OS X é tão ridiculamente lento?

36

Não consigo descobrir por que o lsof no meu Mac (10.8.2, MacBook Pro) é tão lento.

No meu Mac, lsofleva mais de um minuto:

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

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

Em uma caixa típica do Linux, executando o Ubuntu 12.04, são lsofnecessários 20 ms:

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

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

O problema persiste se eu executar lsof -n(para evitar pesquisas de DNS). Além disso, tentei verificar quais chamadas do sistema são feitas lsofusandodtruss e descobri que ele está chamando proc_infodezenas de milhares de vezes:

$ 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

Alguma ideia? Eu executei esses testes e obtive os mesmos resultados usando a versão dolsof incluída no OS X (4.85) e a versão mais recente de ftp://sunsite.ualberta.ca/pub/Mirror/lsof/ (4.87).

(Para os curiosos, a razão pela qual estou frustrado com esse desempenho é que, ao arrastar imagens para o Evernote, ele é executado lsofno processo de cópia do arquivo, fazendo com que meu sistema fique travado por um minuto inteiro sempre que tento inserir uma imagem no Evernote.)

Jason
fonte
1
Se você tiver uma saída para o console em vez de um arquivo, ele será interrompido em um ponto específico? Eu também estou no 10.8.2. Demorou 6 segundos para mim, e notei que ele estava pendurado todas as vezes na metade da lista dos arquivos abertos do AirServer. Eu matei o AirServer e o tempo caiu para 1,76s. Talvez exista algo em seu sistema que demore muito para avaliar?
Warren Pena
Ponto de dados interessante, @WarrenPena. Se eu executar lsofsem argumentos (para listar todos os arquivos), ele será interrompido por um minuto e depois imprimirá todos os arquivos. Mas, como mencionei, ainda trava se eu tentar listar quem tem um único arquivo aberto no diretório / tmp, portanto, esse não é um arquivo aberto específico que é o problema. Além disso, não estou executando nenhum processo AirServer.
5133 Jason
2
Isso leva apenas um segundo para mim. Você também pode tentar sudo opensnoop -n lsof.
Lri
2
Leva 19 s para mim. Não faço ideia porquê ...
daviewales
Boa ideia, @LauriRanta. Tentei correr sudo opensnoop -n lsofe lsof /tmp/testfileem duas guias, e o opensnoop relatou apenas que três arquivos foram abertos. Portanto, o problema não deve ser um número excessivo de arquivos abertos, mas algo relacionado a proc_infochamadas excessivas .
6133 Jason

Respostas:

10

De acordo com minha experiência, do Mac OS X 10.7 (Lion) ao 10.11.5 (EI Capitan), o lsoftravamento sempre.

Para resolver o problema, anexe a -nopção.

lsof -n

De acordo com o manual de lsof, a -nopção:

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: Se ainda estiver lento, você pode tentar

-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

A melhor maneira de descobrir por que é tão lento executar a ferramenta "Instruments" (no ícone do Spotlight Search no canto superior direito) para fazer um "System Trace" em / usr / sbin / lsof e ver as chamadas de gráfico e sys.

insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui

osexp2003
fonte
2
Uau! Adicionando -ncortar meu lsof +Dpara baixo de 5.31 realpara 0.25 real. Esta opção é para ... real
wetjosh
2
Ainda ridiculamente lento para mim ...
Noldorin
Oi, @Noldorin, você está no mesmo sistema operacional que este tópico antigo? Caso contrário, uma nova pergunta específica que se vincule aqui à sua configuração e momento específico poderá valer uma nova resposta.
bmike
3

Acho que a maior parte do problema é que o macOS está se tornando cada vez mais ridículo com inchaço e camadas desnecessárias sobre camadas de estruturas inúteis. Isso significou centenas de processos extras e milhares de arquivos extras sendo mantidos abertos, aumentando a quantidade de trabalholsof a em pelo menos uma ordem de magnitude e, talvez, mais como duas ordens.

lsof passou de velocidade razoável para atrozmente lento entre 10,6 e 10,13.

Aqui em um sistema 10.13.4 atual, vejo o seguinte com apenas 7 aplicativos abertos e em execução (Terminal, Chrome, Calendário, Finder, Adium, IPGadget e Stickies). (O Chrome tem 7 janelas, com talvez 10 guias cada.)

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

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

Durante a execução, ambas as CPUs têm mais de 50% de tempo do sistema

-OÀs vezes, adicionar ajuda, principalmente se lsofnão tiver sido executado ultimamente, mas o melhor que eu vi foi cerca de 10% de economia. Geralmente é minúsculo e provavelmente não vale os riscos descritos na página de manual:

# time lsof -lnPO | wc -l
   10994

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

dtrussalega que existem mais de 89.000 chamadas proc_info()com minha carga de processo atual, e essas estão no kernel e, como timerelatórios, a grande maioria do tempo gasto está no kernel. Não sei por que existem cerca de 8 chamadas por arquivo aberto.

Infelizmente, o macOS / Darwin não inclui o fstatcomando BSD cada vez mais útil e eficiente .

Greg A. Woods
fonte
1

Eu não tenho uma ótima resposta por que seu sistema parece demorar um minuto a mais do que o meu Mac mais lento para ligar proc_info30 mil vezes, mas seu tempo mostra que o Linux e o OS X estão na faixa de 10 ms para que o tempo do usuário execute lsof. Você pode reproduzir o tempo lento de inicialização no modo de segurança para descartar outras cargas na sua CPU?

Eu tentei três Macs e os que executam 10.7.5 são cerca de um segundo mais rápidos que o meu Mac 10.8.2. O sistema operacional mais antigo é um processador Core 2 Duo mais lento e eu acho que um Mac i7 executando o sistema operacional mais recente seria tão rápido ou mais rápido que o sistema operacional e a CPU mais antigos, mas eu estaria errado.

Todas as máquinas fazem o mesmo número de chamadas proc_info, e todas as máquinas têm um tempo de usuário limitado para o comando - mas você pode ter um tempo geral mais lento (e eu não tenho idéia do por que o seu é tão drasticamente mais lento que o meu leão da montanha) Mac).

11 polegadas Air (i7) 2011 executando o 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 de 15 polegadas executando o 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 de 27 polegadas executando o 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
fonte
1
+1. Estou executando o 10.8.2 em um MBP do final de 2010 (i7 + 8GB) e, enquanto estou executando vários aplicativos, estou recebendo ~ 1.8s.
Harv