为什么OS X上的lsof如此缓慢?


36

我不知道为什么Mac(10.8.2,MacBook Pro)上的lsof这么慢。

在我的Mac上,lsof需要一分钟以上的时间:

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

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

在运行Ubuntu 12.04的典型Linux机器上,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

有任何想法吗?我已经运行了这些测试,并使用lsofOS X随附的版本(4.85)和ftp://sunsite.ualberta.ca/pub/Mirror/lsof/(4.87)的最新版本获得了相同的结果。

(出于好奇,我对这种性能感到沮丧的原因是当我将图像拖到Evernote时,它lsof在复制文件的过程中运行,导致我每次尝试插入图像时系统挂起一整分钟在Evernote中。)


1
如果您将其输出到控制台而不是文件,它是否挂在特定位置?我也在10.8.2上。对我来说,这花了6秒钟,我注意到它在列出AirServer的打开文件的中途每次都挂起。我杀死了AirServer,时间降到了1.76s。也许您的系统上有一些东西需要很长时间才能评估?
沃伦·佩纳

有趣的数据点@WarrenPena。如果我lsof不带任何参数运行(以列出所有文件),它将挂起一分钟,然后打印所有文件。但是,正如我提到的,如果我尝试列出谁在/ tmp目录中打开了一个文件,它仍然会挂起,因此问题不是特定的打开文件。另外,我没有运行任何AirServer进程。
杰森

2
(仅?)对我来说大约需要一秒钟。您也可以尝试sudo opensnoop -n lsof
Lri

2
我花了19秒。不知道为什么...
daviewales

好主意,@ LauriRanta。我试图运行sudo opensnoop -n lsoflsof /tmp/testfile在两个选项卡,并opensnoop只报道了三个文件已被打开。因此,问题一定不是文件打开过多,而是与过度proc_info调用有关。
杰森

Answers:


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搜索图标)在/ usr / sbin / lsof上执行“系统跟踪”,然后查看图表和sys调用。

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明


2
哇!再加-n上将我lsof +D从减少5.31 real0.25 real。此选项适用于...真实
wetjosh

2
对于我来说仍然很可笑...
Noldorin 18'Apr

嗨,@ Noldorin,您是否与此旧线程在同一操作系统上?如果没有,那么在这里链接您的特定设置和特定时间的新特定问题可能值得一个新答案。
bmike

3

我认为问题的最大部分在于,macOS变得越来越荒唐,浪费的框架层上充斥着不必要的层。这意味着数百个额外的进程和数千个额外的文件处于打开状态,这lsof使得要做的工作量至少增加了一个数量级,甚至可能增加了两个数量级。

lsof 从合理的速度降到了10.6和10.13之间的惊人速度。

在当前的10.13.4系统上,我看到只有7个已打开并正在运行的应用程序(终端,Chrome,日历,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

在运行期间,两个CPU的系统时间都远远超过50%

-O有时添加帮助,尤其lsof是在最近没有运行过的时候,但是我看到的最好结果是节省了大约10%。通常它很小,可能不值得手册页中概述的风险:

# time lsof -lnPO | wc -l
   10994

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

dtrussproc_info()我的当前进程负载有89,000多个调用,这些调用已进入内核,并且据time报道,所花费的绝大部分时间都在内核中。我不知道为什么每个打开的文件大约有8个调用。

可悲的是,macOS / Darwin没有包含越来越有用和高效的BSD fstat命令。


1

我没有一个很好的答案,为什么您的系统似乎比我最慢的Mac调用proc_info3万次要花费一分钟多的时间,但是您的计时表明,运行lsof所需的用户时间,Linux和OS X都在10毫秒范围内。您是否可以重现以安全模式启动的缓慢时间,以排除CPU上的其他负载?

我试过三台Mac,运行10.7.5的Mac比我的10.8.2 Mac快一秒钟。较旧的操作系统是较慢的Core 2 Duo处理器,我认为运行较新的操作系统的i7 Mac将比较早的操作系统和CPU快或快,但我会错。

所有的机器都进行相同数量的proc_info调用,并且所有机器的命令用户时间都很有限-但是您的总体时机可能会更慢(我不知道为什么您的机器比我的Mountain Lion机器要慢得多苹果电脑)。

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 

运行Lion Server的15英寸MacBook Pro-硬盘:

$ 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

1
+1。我在2010年末的MBP(i7 + 8GB)上运行10.8.2,同时运行许多应用程序时,我的速度约为1.8秒。
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.