Почему lsof на OS X так нелепо медленен?

36

Я не могу понять, почему lsof на моем Mac (10.8.2, MacBook Pro) такой медленный.

На моем Mac lsofзанимает больше минуты:

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

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

На типичном Linux-компьютере с Ubuntu 12.04 lsofтребуется 20 мс:

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

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

Проблема сохраняется, если я запускаю lsof -n(чтобы избежать поиска DNS). Кроме того, я попытался проверить, какие системные вызовы выполняются с lsofпомощью dtruss, и обнаружил, что он вызывает proc_infoдесятки тысяч раз:

$ 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

Любые идеи? Я провел эти тесты и получил те же результаты, используя как версию, lsofвключенную в OS X (4.85), так и последнюю версию с ftp://sunsite.ualberta.ca/pub/Mirror/lsof/ (4.87).

(Любопытно, что причина этого разочарования в том, что когда я перетаскиваю изображения в Evernote, он запускается lsofв процессе копирования файла, в результате чего моя система зависает на целую минуту при каждой попытке вставить изображение в Evernote.)

Джейсон
источник
1
Если у вас есть вывод на консоль вместо файла, он зависает в определенной точке? Я тоже на 10.8.2. Это заняло у меня 6 секунд, и я заметил, что оно зависало каждый раз в середине списка открытых файлов AirServer. Я убил AirServer, и время упало до 1,76 с. Возможно, в вашей системе есть что-то, что требует много времени для оценки?
Уоррен Пена
Интересная точка данных, @WarrenPena. Если я запускаю lsofбез аргументов (чтобы вывести список всех файлов), он зависает на минуту, а затем печатает все файлы. Но, как я уже говорил, он все равно зависает, если я пытаюсь перечислить, у кого открыт один файл в каталоге / tmp, поэтому проблема не в конкретном открытом файле. Кроме того, я не запускаю процесс AirServer.
Джейсон
2
Это (только?) Занимает около секунды для меня. Вы также можете попробовать sudo opensnoop -n lsof.
Lri
2
Это занимает 19 секунд для меня.
Понятия
Хорошая идея, @LauriRanta. Я попытался запустить sudo opensnoop -n lsofи lsof /tmp/testfileв двух вкладках, и opensnoop только сообщил, что были открыты три файла. Таким образом, проблема не в чрезмерном количестве открытий файлов, а в том, что они связаны с чрезмерными proc_infoвызовами.
Джейсон

Ответы:

10

Как показывает мой опыт, от Mac OS X 10.7 (Lion) до 10.11.5 (EI Capitan) lsofвсегда зависают.

Чтобы решить проблему, добавьте -nопцию.

lsof -n

Согласно инструкции lsof, -nопция:

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

РЕДАКТИРОВАТЬ 2018-04-25: Если это все еще медленно, вы можете попробовать

-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

Лучший способ выяснить, почему так медленно, - запустить инструмент «Инструменты» (в правом верхнем углу значка Spotlight Search), чтобы выполнить «Системный след» в / usr / sbin / lsof, а затем просмотреть вызовы graph и sys.

введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь

osexp2003
источник
2
Вот Это Да! Добавляем -nруби lsof +Dот 5.31 realк 0.25 real. Этот вариант для ... реального
wetjosh
2
Все еще смехотворно медленный для меня ...
Нолдорин
Привет @ Noldorin ты на той же ОС, как эта старая тема? Если нет, новый конкретный вопрос, связанный здесь с вашей конкретной настройкой и определенным временем, может стоить нового ответа.
bmike
3

Я думаю, что самая большая часть проблемы заключается в том, что macOS становится все более нелепым с раздуванием и ненужными слоями на слоях расточительных платформ. Это означало, что сотни дополнительных процессов и тысячи дополнительных файлов lsofостаются открытыми, увеличивая объем работы, которую необходимо выполнить, по крайней мере, на порядок, а может быть, больше на два порядка.

lsof перешел с разумной скорости на ужасно медленный между 10,6 и 10,13.

Здесь, в текущей системе 10.13.4, я вижу следующее с 7 открытыми и работающими приложениями (Terminal, Chrome, Calendar, Finder, Adium, IPGadget и Stickies). (Chrome имеет 7 окон, по 10 вкладок в каждом.)

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

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

Во время работы оба процессора занимают более 50% системного времени

-OИногда помогает добавление , особенно если lsofоно не запускалось в последнее время, но лучшее, что я видел, было около 10% экономии. Обычно это незначительно и, вероятно, не стоит рисков, описанных на странице руководства:

# time lsof -lnPO | wc -l
   10994

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

dtrussутверждает, что proc_info()с моей текущей загрузкой процесса поступило более 89 000 вызовов , и они относятся к ядру, и, как timeсообщается, подавляющее большинство времени уходит на ядро. Я не знаю, почему на открытый файл приходится около 8 звонков.

К сожалению, macOS / Darwin не содержит еще более полезной и эффективной fstatкоманды BSD .

Грег А. Вудс
источник
1

У меня нет хорошего ответа, почему ваша система, кажется, занимает минуту дольше, чем мой самый медленный Mac, чтобы звонить в proc_info30 тысяч раз, но ваше время показывает, что и linux, и OS X находятся в диапазоне 10 мс для того, чтобы пользователь запускал lsof. Можете ли вы воспроизвести эту медленную загрузку в безопасном режиме, чтобы исключить другие нагрузки на ваш процессор?

Я пробовал три Mac, и те, которые работают с 10.7.5, примерно на секунду быстрее, чем мой Mac с 10.8.2. Старые ОС - более медленные процессоры Core 2 Duo, и я думаю, что i7 Mac с более новой ОС будет работать быстрее или быстрее, чем старые ОС и ЦП, но я ошибаюсь.

Все машины совершают примерно одинаковое количество вызовов proc_info, и у всех машин время команды меньше, чем у пользователя, - но вы можете использовать более медленное общее время (и я не имею ни малейшего представления, почему ваша машина так значительно медленнее, чем мой Mountain Lion). Mac).

11-дюймовый Air (i7) 2011 под управлением 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-дюймовый MacBook Pro с 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-дюймовый iMac под управлением 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
источник
1
+1. Я использую 10.8.2 на MBP в конце 2010 года (i7 + 8 ГБ), и пока я запускаю кучу приложений, я получаю ~ 1.8s.
Harv