Linux性能优化--使用性能工具发现问题

9.0 概述

本章主要介绍综合运用之前提出的性能工具来缩小性能问题产生原因的范围。阅读本章后,你将能够:

  1. 启动行为异常的系统,使用Linux性能工具追踪行为异常的内核函数或应用程序。
  2. 启动行为异常的应用程序,使用Linux性能工具追踪行为异常的函数或源代码行。
  3. 追踪CPU、内存、磁盘I/O和网络的过度使用情况。

9.1并非总是万灵药

本章假设可以通过改变软件来解决性能问题。通过对应用程序或系统调优来达到性能目标并非总是可行的。如果调优失败,就可能要求进行硬件升级或更换。如果系统容量达到极限,那么性能调优就只能起到一定的作用。
举例来说,升级系统内存容量可能是必要的(或者是更便宜的),而不是追踪哪个应用程序在使用系统内存,然后对它们进行调整以降低其使用量。只升级系统硬件而非追踪并调整特定的性能问题,这个决定依赖于问题本身,同时,它也是进行调查的个人的价值判断。它实际上取决于哪种选择更加便宜,是(问题调查的)时间方面,还是(购买新硬件的)经费方面。最后,在某些情况下,调优将是首选或唯一的选择,这就是本章要描述的内容。

9.2开始追踪

当你决定在Linux上优化某些东西之后,你首先要确定的是要优化什么。本章使用的方法覆盖了一些比较常见的性能问题,通过举例来说明如何利用前面介绍的工具共同解决这些问题。接下来的几个小节将帮助引导你找到性能问题的成因。在很多小节中会先要求运行各种性能工具,然后根据结果跳转到本章的其他小节。这有助于找到问题的根源。
就像在前面章节里陈述的一样,保存每次执行的测试结果是一个好办法。这使你能在之后的时间查看结果,假如调查结果尚不能确定,还可以将结果发送给其他人。
现在开始。调查问题的时候,初始系统运行的无关程序越少越好,因此,关闭或终止任何不需要的应用程序或进程。一个干净的系统有助于消除由任何无关应用程序可能导致的混淆干扰。如果某个特定的应用或程序没有按预期执行,直接跳到9.3节。如果不是某个应用程序性能不好,而是整个Linux系统执行效果不如预期,则跳到9.4节。

9.3优化应用程序

优化应用程序时,其执行的多个方面有可能出现问题。本节将根据你发现的问题,将你引导到正确的小节。图9-1展示了优化应用程序的步骤。诊断从9.3.1节开始。
在这里插入图片描述

9.3.1 内存使用有问题?

使用top或ps确定应用程序使用了多少内存。如果该程序消耗的内存量超过预期,转到9.6.6节。否则,继续见9.3.2节。

9.3.2启动时间有问题?

如果应用程序启动所花费的时间有问题,见9.3.3节。否则,转到9.3.4节。

9.3.3 加载器引入延迟了吗?

要测试问题是否出在加载器上,就按前面章节所述来设置ld环境变量。如果ld统计数据显示在映射所有的符号时有明显的延迟,那么就尽量减少应用程序使用的库的数量和大小,或者尽量预链接库。如果加载器确实表现出有问题,转到9.9节。如果没有问题,继续见9.3.4节。

9.3.4 CPU使用(或完成时长)有问题?

用top或ps来确定应用程序的CPU使用量。如果应用程序是CPU消耗大户,或其完成时间特别长,那么该程序就存在CPU使用问题。
通常,一个应用程序的不同部分会具有不同的性能表现。那么就可能需要隔离那些性能不佳的部分,这样使用性能工具时就不用测量那些对性能没有负面影响的部分,而只需要测量被隔离部分的性能统计数据。为此,可能要改变应用程序的行为,使之易于分析。如果应用程序某个特定的部分对性能非常重要,那么在测量整个应用程序的性能统计信息时,要么试着只测量关键部分执行时的性能统计数据,要么就让该部分运行相当长的时间,直到应用程序无关部分的数据在与之不相干的整个性能统计数据中只占一小部分。尽量减少应用程序的工作,以便它只执行对性能至关重要的功能。比方说,在收集一个应用程序整体运行的性能统计信息时,我们不希望启动和退出过程占据大部分的应用程序运行时的总时间量。在这种情况下,比较有效的方法是启动应用程序,多次运行时间消耗大的部分,然后立即退出程序。这样分析工具(如oprofile或gprof)就可以捕获运行缓慢代码的更多信息,而不是那些执行了但却与问题无关部分(如启动和退出)的信息。比这个方法更好的是修改应用程序的源代码,当应用程序启动时,自动运行耗时部分,然后退出程序。这有助于最大程度减少与特定性能问题无关的分析数据。
如果应用程序的CPU使用有问题,转到9.5节。如果没有问题,见9.3.5节。

9.3.5 应用程序的磁盘使用有问题?

如果已经知道应用程序会导致大量的磁盘I/O,转到9.7.3节以确定它访问了哪些文件。否则,见9.3.6节。

9.3.6 应用程序的网络使用有问题?

如果已经知道应用程序会导致大量的网络I/O,转到9.8.6节。
如果上述问题均不存在,你遇到的应用程序性能问题可能就不在本书范围之内,请转到9.9节。

9.4 优化系统

有时候,处理一个行为异常的系统,找出究竟是什么拉低了每件事情的速度是很重要的。由于调查的是系统级的问题,其原因可能存在于任何地方,从用户应用程序到系统库,再到Linux内核。幸运的是,与很多别的操作系统不同,对Linux来说,即使不能得到系统上所有应用程序的源代码,也可以获取其中大多数的源代码。如果有必要的话,你可以修复这个问题并将其提交给该部分的维护者。最糟糕的情况也不过是在本地运行已修复的版本。这就是开源软件的力量。
图9-2展示的是诊断系统级性能问题的流程。
在这里插入图片描述
调查从9.4.1节开始。

9.4.1系统是受CPU限制的吗?

使用top、procinfo或mpstat来确定系统在哪些地方消耗了时间。如果整个系统空闲和等待时间的比例不足全部时间的5%,那么该系统就是受CPU限制的。转到9.4.3节。否则,前进到9.4.2节。

9.4.2 单个进程是受CPU限制的吗?

虽然系统作为一个整体可能不是受CPU限制的,但在一个对称多处理(SMP)或超线程系统中,单个处理器可能是受CPU限制的。
使用top或mpstat来确定单个CPU的空闲和等待时间是否少于5%。如果是,那么一个或多个CPU就是受CPU限制的,对这种情况,转到9.4.4节。否则,各处理器都不是受CPU限制的,则转到9.4.7节。

9.4.3一个或多个进程使用了大多数的系统CPU吗?

下一步是要找出是否有特定应用程序或应用程序组使用了CPU。最简单的方法是运行top。默认情况下,top按CPU使用量的降序来排列进程。top按照该进程消耗的用户时间和系统时间总和来报告进程的CPU使用量。举个例子,如果一个应用程序在用户空间代码上消耗了20%CPU时间,在系统代码上消耗了30%CPU时间,那么,top将会报告该进程消耗了50%CPU时间。将所有进程的CPU时间加起来,如果这个时间明显少于整个系统的系统时间加用户时间,那么内核所做的重要工作就与应用程序无关,转到9.4.5节。
否则,每个进程都转9.5.1节一次,以便确定时间是在哪里消耗的。

9.4.4一个或多个进程使用了单个CPU的大多数时间?

下一步是要找出是否有特定应用程序或应用程序组使用了单个CPU。实现该目标最简单的方法是运行top。默认情况下,top按CPU使用量的降序来排列进程。在报告进程的CPU使用量时,top显示的是应用程序使用的总CPU和系统时间。举个例子,如果应用程序在用户空间代码上消耗了20%的CPU,在系统代码上消耗了30%的CPU时间,那么,top将会报告该应用程序消耗了50%的CPU时间。
首先,运行top,然后将最后一个CPU添加到top显示的字段中。打开Irix模式,以便top显示每个处理器使用的CPU时间总量而不是整个系统的CPU时间。对于每个利用率高的处理器,将其上运行的特定应用程序或多个应用程序的CPU时间加起来。如果在一个CPU上,应用程序时间总和低于内核加用户时间之和的75%,这表明内核似乎花了大量的时间在其他的工作上而不是在应用程序上。对这种情况,见9.4.5节。否则,应用程序很有可能就是CPU消耗量的原因,对每个应用程序,转到9.5.1节。

9.4.5 内核服务了许多中断吗?

这看起来好像是内核花费了大量时间完成那些不代表应用程序的工作。对这种情况的一种解释是I/O卡提交了很多中断,比如,一个忙碌的网卡。运行procinfo或cat/proc/interrupts来确定有多少中断被提出,其提出频率是怎样的,以及哪些设备导致了这些中断。这可能为系统的行为提供线索。将这些信息记录下来,并进入9.4.6节。

9.4.6 内核的时间花在哪儿了?

最后要搞清楚的是内核究竟做了些什么。在系统上运行oprofile,记录下哪些内核函数消耗了大量的时间(超过总时间的10%)。尝试阅读这些函数的内核源代码,或是在Web上搜索这些函数的引用。可能不会立即弄清楚这些函数的功能,但是可以试着找出它们在哪个内核子系统中。仅仅确定使用的是哪个子系统(如内存、网络、调度或磁盘)可能就足以判断是哪里出了问题。
知道这些函数的功能还有可能了解到它们被调用的原因。如果函数是设备特定的,就要试着找出为什么要使用特定的设备(尤其是如果它还有大量的中断)。向其他发现同样问题的人发电子邮件,有可能的话,与内核开发人员联系。
转到9.9节。

9.4.7 交换空间的使用量在增加吗?

下一步是检查交换空间的使用量是否在增加。不少系统级性能工具,如top、vmstat、procinfo和gnome-system-info等都会提供这个信息。如果交换空间在增加,就需要找出是系统的哪个部分消耗了更多的内存。要实现这个目的,请转到9.6.1节。
如果被使用的交换空间没有增加,则见9.4.8节。

9.4.8系统是受I/O限制的吗?

运行top时,查看系统是否在等待状态上消耗了大量的时间。如果这个时间比例超过了50%,那么系统就在等待I/O上消耗了相当多的时间,我们就要确定这个I/O是哪种类型,见9.4.9节。
如果系统没有花大量的时间等待I/O,那么你遇到的问题就不在本书范围之内,则转到9.9节。

9.4.9 系统使用磁盘I/O吗?

接下来,运行vmstat(或iostat)并查看磁盘读写的块数。如果磁盘读写的块数很大,那么这可能就是磁盘瓶颈,转到9.7.1节。否则,继续见9.4.10节。

9.4.10 系统使用网络I/O吗?

接下来,我们要查看系统是否使用了大量的网络I/O。最简单的方法是运行iptraf、ifconfig或sar来找出每个网络设备上传输了多少数据。如果网络流量接近网络设备的容量,那么就可能是网络瓶颈,则转到9.8.1节。如果看上去没有网络设备进行了网络通信,那么内核等待的是没有包含在本书范围内的其他一些I/O设备。查看内核调用了哪些函数以及哪些设备向内核发起了中断可能会有所帮助,转到9.4.5节。

9.5优化进程CPU使用情况

当确定了某特定进程或应用程序是CPU瓶颈后,就必须查明其消耗时间的位置(和原因)。图9-3展示了调查进程CPU使用情况的方法。调查从9.5.1节开始。
在这里插入图片描述

9.5.1进程在用户还是内核空间花费了时间?

你可以用time命令来确定一个应用程序是否在内核或用户模式下消耗了时间。oprofile 也可以用来确定时间花在了哪里。通过分析每一个进程,能够看到一个进程是否将其时间花在了内核或用户空间。
如果应用程序在内核空间消耗了大量的时间(超过25%),见9.5.2节。否则,转到9.5.3节。

9.5.2 进程有哪些系统调用,完成它们花了多少时间?

下一步,运行strace来查看有哪些系统调用以及它们完成的时长是多少。你还可以运行oprofile找出哪些内核函数被调用了。
减少系统调用的次数或者改变代表程序进行的系统调用都有可能提升性能。有些系统调用可能是意想不到的,是应用程序调用各种库的结果。你可以运行ltrace和strace来帮助确定它们被调用的原因。
现在问题已经明确了,就由你来解决它,转到9.9节。

9.5.3进程在哪些函数上花了时间?

下一步,使用周期事件在应用程序上运行oprofile,确定哪些函数使用了全部的CPU 周期(即,哪些函数消耗了所有应用程序时间)。
记住,尽管oprofile可以向你显示在一个进程上花费了多少时间,但是在进行函数级分析时,一个特定函数成为热点的原因是由于其频繁被调用,还是仅仅由于其完成时间很长,是无法弄清楚的。
一种能弄明白上述两种情况中哪种是正确的方法是:从oprofile获得源代码级注释,并查找应该几乎没有开销的指令/源代码行(如赋值)。相对于其他高成本的源代码行,它们的样本数量将接近于函数被调用的次数。再次声明,这仅仅是近似的,因为oprofile只采样了CPU,乱序处理器会误判一些周期。
做出函数的调用图对明确热点函数是如何被调用的也是有帮助的。实现这个目的,见9.5.4节。

9.5.4热点函数的调用树是怎样的?

接下来,你可以找出耗时函数是怎么被调用的及其被调用的原因。把应用程序与gprof 一起运行能够显示每个函数的调用树。如果耗时函数在一个库中,你可以使用1trace来查看是哪些函数。最后,你可以使用oprofile较新的版本来支持调用树的跟踪。还有一种方法,你可以在gdb中运行应用程序,在热点函数上设置断点。然后运行该应用程序,在每次调用热点函数时,它都会暂停。此时,可以生成一个回溯,看看究竟是哪些函数和源代码行产生了这个调用。
知道是哪些函数调用了热点函数能够让你消除或减少对这些函数的调用,相应地加快应用程序的速度。如果减少对耗时函数的调用不能加快应用程序,或者无法消除这些函数,见9.5.5节。否则,转到9.9节。

9.5.5 Cache缺失与热点函数或源代码行是对应的吗?

下一步,针对你的应用程序运行oprofile、cachegrind和kcache,看看耗时函数或源代码行是否具有大量的cache缺失。如果是,则尝试重新安排或压缩你的数据结构和访问,让它们变得更加cache友好。如果热点代码行没有高cache缺失率,那么就尝试重新安排你的算法来减少特定行或函数执行的次数。
在任何情况下,工具都会尽其所能地向你提供信息,转到9.9节。

9.6优化内存使用情况

一般,要使用大量内存的应用程序通常会导致其他一些性能问题的产生,比如cache缺失、转换后援缓冲器(TLB)缺失以及交换。
图9-4展示了我们在试图弄清楚系统内存使用情况时的决策流程。调查从9.6.1节开始。

9.6.1内核的内存使用量在增加吗?

要追踪谁使用了系统内存,首先要确定内核自身是否分配内存。运行slabtop查看内核的内存总大小是否增加。如果增加了,则跳到9.6.2节。
如果内核的内存使用量没有增加,那么可能是特定进程导致了用量增加。要追踪是哪个进程该为内存使用量的增加负责,转到9.6.3节。

9.6.2 内核使用的内存类型是什么?

如果内核的内存使用量在增加,就再次运行slabtop来确定内核分配的内存类型。分片的名字多少会暗示一下内存被分配的原因。通过Web搜索,你可以找到内核源代码中每个分片名字的更多详细信息。只需在内核源代码中搜索该分片的名字,并确定它被用于哪些文件,就有可能弄清楚它被分配的原因。在明确了哪些子系统分配了所有的内存后,可以尝试调整特定子系统可以消耗的最大内存量,或者减少该子系统的使用量。
转到9.9节。
在这里插入图片描述

9.6.3特定进程的驻留集大小在增加吗?

接下来,你可以使用top或ps来查看特定进程的驻留集大小是否在增加。最简单的方法是在top的输出中添加rss字段,并按照内存使用量来排序。如果一个特定进程不断增加内存的使用量,我们就需要弄清楚它用的内存类型是什么。要弄清楚应用程序使用的内存是什么类型,转到9.6.6节。如果没有特定进程使用了更多内存,则见9.6.4节。

9.6.4共享内存的使用量增加了吗?

使用ipcs来确定被使用的共享内存的数量是否在增加。如果是,见9.6.5节以确定哪些进程在使用内存。否则,你遇到是不在本书讨论范围内的系统内存泄露问题,转到9.9节。

9.6.5哪些进程使用了共享内存?

用ipcs来确定哪些进程使用并分配了共享内存。确定了使用了共享内存的进程之后,就调查各个进程来找出它们为什么使用内存。比如,在应用程序的源代码中寻找对shmget (分配共享内存)或shmat(附加到它上面)的调用。阅读应用程序的文档,查找解释并减少其共享内存使用的选项。
尝试减少共享内存使用量并转到9.9节。

9.6.6进程使用的内存类型是什么?

找出进程使用的内存类型最简单的方法是在/proc文件系统中查看其状态。文件cat /proc//status给出了进程内存使用情况的详细信息。
如果进程具有大的VmExe值,这就意味着可执行文件很大。要指明可执行文件中哪些函数导致了这个大小,请转到9.6.8节。如果进程具有大的VmLib值,这就意味着该进程使用了大量的共享库,或是几个体积较大的共享库。要指明哪些库导致了这个大小,请转到9.6.9节。如果进程的VmData值较大并且在增加,这就意味着该进程的数据区或堆在增加。要分析其原因,请转到9.6.10节。

9.6.7 哪些函数正在使用全部的栈?

要找出哪些函数分配了大量的栈,我们必须使用gdb和一点点技巧。第一步,使用gdb 附加到正在运行的进程。第二步,用bt要求gdb产生回溯。第三步,(在i386上)用info registers esp输出栈指针。这个输出就是栈指针的当前值。现在键入up并输出栈指针。前面栈指针和当前栈指针的差值(十六进制)就是前一个函数使用的栈容量。继续这样up回溯,你将可以发现哪个函数使用了大部分的栈。
当你确定了哪个函数或函数组消耗了大部分的栈之后,你可以修改应用程序,减少该函数(或这些函数)的调用次数和大小。转到9.9节。

9.6.8 哪些函数的文本大小最大?

如果可执行文件使用了相当可观的内存容量,那么确定哪些函数占用了最多的空间,并删除不必要的函数可能会有所帮助。对一个可执行文件或符号编译的库来说,可以请求nm显示所有符号的大小,并用如下命令对它们进行排序:
nm -S -size-sort
了解每个函数的大小后,就可能减少它们的大小或者从应用程序中移除不必要的代码。转到9.9节。

9.6.9进程使用的库有多大?

要了解进程使用了哪些库以及这些库各自的大小,最简单的方法是查看/proc文件系统中的进程映射。文件cat /proc//map显示的是每个库及其代码与数据的大小。当你知道进程使用了哪些库之后,就有可能淘汰对大型库的使用,或者是用小一点的库来代替它们。但是,这样做的时候必须要小心,因为移除大型库未必会减少整个系统的内存使用量。
如果某库正在被其他任何应用程序使用(可以运行lsof来确定该库),库就已经被加载到了内存。任何新应用程序在使用这个库的时候都不需要再加载一个该库的副本到内存。让程序转而使用不同的库(即使是个小库)实际上就会增加总的内存使用量。这个新的库没有被其他进程使用,因此需要为其分配新的内存。最好的解决方法是缩小库自身的大小,或是修改它们以便使用更少的内存来保存库的特定数据。如果可行,则所有的应用程序都将受益。
要了解特定库中函数的大小,转到9.6.8节。否则,转到9.9节。

9.6.10 哪些函数分配堆内存?

如果你的应用程序是用C或C++编写的,就可以使用内存剖析器memprof来找出哪些函数分配了堆内存。memprof能够动态展示应用程序使用的内存量是如何增长的。
如果你的应用程序是用Java编写的,就在java命令行上添加-Xrunhprof命令行参数,它将会给出应用程序分配内存的详细信息。如果你的应用程序是用C#(Mono)编写的,就在mono命令行上添加-profile命令行参数,它也会给出应用程序分配内存的详细信息。
当你知道了哪些函数分配了最多的内存之后,就有可能减少被分配的内存大小。由于内存便宜,且越界错误很难被侦测到,因此,为了安全考虑,程序员常常超量分配内存。然而,如果一个特定的分配导致了内存问题,那么仔细分析最小分配就可能在保证安全的前提下,显著减少内存使用量。转到9.9节。

9.7优化磁盘I/O使用情况

当你确定是磁盘I/O有问题后,明确是哪个应用程序引起了I/O就会有所帮助。图9-5给出了确定磁盘I/O使用原因的步骤。调查从9.7.1节开始。

9.7.1系统强调特定磁盘吗?

在扩展统计模式下运行iostat,寻找平均等待(await)大于零的分区。await是等待请求被响应所平均花费的毫秒数。这个数值越高,则磁盘超负荷越多。可以通过查看磁盘的读写流量并确定其是否接近该驱动器可以处理的最大量来确认超负荷。
如果单个驱动器上的很多文件都被访问了,那么,将这些文件分散到多个磁盘就可能提高性能。不过,首先要确定的是哪些文件被访问了。
转到9.7.2节。
在这里插入图片描述

9.7.2 哪个应用程序访问了磁盘?

在前面关于磁盘I/O的章节中已经介绍过,确定哪个进程导致了大量的I/O是有难度的,因此,我们必须在缺少直接实现该功能工具的情况下来试着解决这个问题。通过运行top,首先寻找非空闲进程。对于每个这样的进程,转到9.7.3节。

9.7.3 应用程序访问了哪些文件?

首先,通过strace,用strace -e trace=file来追踪应用程序中所有与文件I/O相关的系统调用。然后strace用摘要信息来查看每个调用花费的时长。如果某些读写调用完成时间很长,那么这个进程可能造成了I/O的缓慢。在正常模式下运行strace就可以发现是从哪个文件描述符进行读写的。要把这些文件描述符映射回文件系统中的文件,我们可以查看proc 文件系统。/proc//fd/中的文件是从文件描述符到实际文件的符号链接。该目录下的ls -la 会显示进程使用了哪些文件。通过了解进程访问的文件,就有可能减少该进程执行的I/O 量,将其更均匀地分散于多个磁盘,或者将其迁移到更快的磁盘。
确定进程访问哪些文件后,转到9.9节。

9.8优化网络I/O使用情况

当知道网络发生了问题时,Linux提供了一组工具来确定哪些应用程序涉及其中。但是,在与外部机器连接时,对网络问题的修复就不完全由你控制了。图9-6展示了调查网络性能问题的步骤。调查从9.8.1节开始。
在这里插入图片描述

9.8.1网络设备发送/接收量接近理论极限了吗?

要做的第一件事就是用ethtool来确定每个Ethernet设备设置的硬件速度是多少。如果有这些信息的记录,就可以调查是否有网络设备处于饱和状态。Ethernet设备和/或交换机容易被误配置,ethtool显示每个设备认为其应运行的速度。在确定了每个Ethernet设备的理论极限后,使用iptraf(甚至是ifconfig)来明确流经每个接口的流量。如果有任何网络设备表现出饱和,转到9.8.3节。否则,转到9.8.2节。

9.8.2 网络设备产生了大量错误吗?

网络流量减缓的原因也可能是大量的网络错误。用ifconfig来确定是否有接口产生了大量的错误。大量错误可能是不匹配的Ethernet卡/Ethernet交换机设置的结果。联系你的网络管理员,在Web上搜索遇到类似问题的人,或者把问题e-mail给一个Linux网络新闻组。
转到9.9节。

9.8.3设备上流量的类型是什么?

如果特定设备正在服务大量的数据,使用iptraf可以跟踪该设备发送和接收的流量类型。当知道了设备处理的流量类型后,转到9.8.4节。

9.8.4特定进程要为流量负责吗?

接下来,我们想要确定是否有特定进程要为这个流量负责。使用netstat的-p选项来查看是否有进程在处理流经网络端口的类型流量。如果有应用程序要对此负责,转到9.8.6节。如果没有这样的程序,则转到9.8.5节。

9.8.5流量是哪个远程系统发送的?

如果没有应用程序应对这个流量负责,那么就可能是网络上的某些系统用无用的流量攻击了你的系统。要确定是哪些系统发送了这些流量,要使用iptraf或etherape。
如果可能的话,请与系统所有者联系,并尝试找出发生这种情况的原因。如果所有者无法联系上,可以在Linux内核中设置ipfilters,永久丢弃这个特定的流量,或者是在远程机与本地机之间建立防火墙来拦截该流量。
转到9.9节。

9.8.6 哪个应用程序套接字要为流量负责?

确定使用了哪个套接字要分两步。第一步,用strace-e trace=file跟踪应用程序所有的I/O系统调用。这能显示进程是从哪些文件描述符进行读写的。第二步,通过查看proc文件系统,将这些文件描述符映射回套接字。/proc//fd/中的文件是从文件描述符到实际文件或套接字的符号链接。该目录下的1s-la会显示特定进程全部的文件描述符。名字中带有socket的是网络套接字。之后就可以利用这些信息来确定程序中的哪个套接字产生了这些通信。
转到9.9节。

9.9 尾声

当你看到这里的时候,你的问题可能得到也可能没有得到解决,但是,你会获取大量描述它的信息。在Web和新闻组上搜索遇到相同问题的人,向他们和开发者发电子邮件,看看他们是如何解决问题的。尝试一个解决方案,并观察系统或应用程序的行为是否发生了变化。每次尝试新方案时,请转到9.2节重新开始系统诊断,因为,每一个修复都可能会让应用程序的行为发生变化。

9.10本章小结

本章提供了综合运用Linux性能工具跟踪不同类型性能问题的方法。虽然这个方法不可能捕捉到每一种可能出错的性能问题,但是它有助于发现一些比较常见的问题。此外,即便你面对的问题在这里没有涉及,你所收集的数据仍然是有用的,因为,这些数据可能会开启调查的不同方面。
接下来的几章将演示如何在Linux系统中使用该方法找出性能问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/108726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新加坡服务器托管

新加坡是一个小而繁荣的国家,是东南亚唯一一个发达国家。它地理位置好,毗邻马来西亚和印度尼西亚,新加坡是一个拥有先进科技和强大经济的国家,主要以制造业、金融、旅游和航运为主,拥有先进的经济和现代化的基础设施&a…

C++进阶篇1---继承

一、继承的概念和定义 1.1概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称为派生类。继承呈现了面向对象程序设计的层次结构&#xff…

AFL模糊测试+GCOV覆盖率分析

安全之安全(security)博客目录导读 覆盖率分析汇总 目录 一、代码示例 二、afl-cov工具下载 三、编译带覆盖率的版本并启动afl-cov 四、AFL编译插桩并运行afl-fuzz 五、结果查看 AFL相关详见AFL安全漏洞挖掘 GCOV相关详见GCOV覆盖率分析 现将两者结合,即进…

添加Mybatis框架支持

配置环境 1.老项目 在pom.xml中使用generate ->edit starts->添加下面俩 2.新项目 然后运行发现会有报错 2.1这是因为没有配置数据库连接信息 spring:datasource:url: jdbc:mysql://localhost:3306/java2023?characterEncodingutf8&useSSLfalse # MySQL数…

为什么学校互联网专业教的只是出社会都没用?

今日话题,为什么很多学生都觉得认真学习了学校课程,但是出社会企业发现一点用都没有?解决方法放在了后方,免费领取。首先,计算机技术的迅猛发展导致学校教材和课程更新滞后,可能学到的知识已是老旧。嵌入式…

JNDI-Injection-Exploit工具安装

从github上下载安装 git clone https://github.com/welk1n/JNDI-Injection-Exploit.git 打开 cd JNDI-Injection-Exploit 编译安装,Maven入门百科_maven中quickstart是什么意思-CSDN博客 mvn clean package -DskipTests 因为提示mvn错误,解决下…

leetcode-200. 岛屿数量

1. 题目 leetcode题目链接 2. 解答 思路: 需要循环遍历每个节点;找到陆地,基于陆地开始遍历陆地的上下左右;数组dirm dirn就可以表示某个区域的上下左右;标记遍历过的节点;设计循环的退出条件&#xf…

嵌入式实时操作系统的设计与开发(调度策略学习)

将调度分为两层,上层为策略,下层为机制,并且采用策略与机制分离的设计原则,可以方便灵活地扩展调度策略,而不改变底层的调度机制。 调度策略就是如何确定线程的CPU、优先级prio等参数,线程是按照FIFO&…

【LeetCode刷题(数据结构)】:检查两颗树是否相同

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的 输入:p [1,2,3], q [1,2,3] 输出:true 输入:p [1,2], q [1,…

05_51单片机led流水线的实现

1:step创建一个新的项目并将程序烧录进入51单片机 以下是51单片机流水线代码的具体实现 #include <REGX52.H>void Delay500ms() //11.0592MHz {unsigned char i, j, k;i 4;j 129;k 119;do{do{while (--k);} while (--j);} while (--i); }void main(){while(1){P1 0…

【性能测试篇1】初识性能测试

目录 性能测试定义 性能测试和功能测试有什么区别 测试工具上面&#xff1a; 特殊业务场景下&#xff1a; 性能测试常见概念&#xff1a; ①用户相关&#xff1a; 1.1并发用户数&#xff1a; 1.2在线用户数&#xff1a; 1.3系统用户数量&#xff1a; ②响应时间相关&…

SpringMVC之国际化上传下载

spring项目中的国际化 1&#xff09;提供中英两种资源文件 i18n_en_US.properties i18n_zh_CN.properties 2&#xff09;配置国际化资源文件&#xff08;在spring配置文件中添加&#xff0c;例如spring-mvc.xml&#xff09; <bean id"messageSource" class&quo…

通达OA 2016网络智能办公系统 handle.php SQL注入漏洞

一、漏洞描述 北京通达信科科技有限公司通达OA2016网络智能办公系统 handle.php 存在sql注入漏洞&#xff0c;攻击者可利用此漏洞获取数据库管理员权限&#xff0c;查询数据、获取系统信息&#xff0c;威胁企业单位数据安全。 二、网络空间搜索引擎查询 fofa查询 app"T…

【STL】平衡二叉树

前言 对于之前普通的二叉搜索树&#xff0c;其搜索的效率依靠树的形状来决定&#xff0c;如下&#xff1a; 可以看到 A图 中的树比较彭亨&#xff0c;搜索一个元素的效率接近 O(logN) &#xff1b;而 B图 中的形状也符合搜索二叉树&#xff0c;但是很不平衡&#xff0c;这时的…

框架篇

一、Spring中的单例Bean是线程安全的吗 二、AOP相关面试题 三、Spring中的事务 四、Spring中事务失效的场景有 五、Spring bean的生命周期 六、Spring的循环依赖 七、SpringMVC的执行流程 八、自动配置原理 九、Spring框架常见的注解 十、Mybatis的执行流程 十一、MyBatis延迟加…

(转)tinymce-vue使用教程

一、资源下载 npm install tinymce -S //当前版本^5.1.1 npm install tinymce/tinymce-vue -S //当前版本^3.0.1二、安装语言包 资源下载后,在 node_modules 中找到 tinymce/skins 目录&#xff0c;然后将 skins 目录拷贝到 static 目录下,(PS: 如果是使用 vue-cli 3.x 构建…

前端开发tips

vue配置启动项目自动打开浏览器 打开package.json找到启动命令npm run dev 跟npm run serve(这两种命令都可以) 后面增加 --open Vue项目设置路径src目录别名为 Vue2 编辑vue.config.js内容如下&#xff1a; const { defineConfig } require(vue/cli-service)const path…

STM32Cube高效开发教程<基础篇>(六)----FSMC连接TFT-LCD屏

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。    本专栏博客参考《STM32Cube高效开发教程(基础篇)》,有意向的读者可以购买正版书籍辅助学习,本书籍由王维波老师、鄢志丹老师、王钊老师倾力打造,书籍内容干货满满。 一、 FSMC连接…

LeetCode34 在排序数组中寻找元素的第一个和最后一个位置

题目&#xff1a; 思路&#xff1a; https://blog.csdn.net/wangjiaqi333/article/details/124526112 直观的思路肯定是从前往后遍历一遍。用两个变量记录第一次和最后一次遇见target的下标&#xff0c;但这个方法的时间复杂度为O(n)&#xff0c;没有利用到数组升序排列的条件…

小程序-uni-app:将页面(html+css)生成图片/海报/名片,进行下载 保存到手机

一、需要描述 本文实现&#xff0c;uniapp微信小程序&#xff0c;把页面内容保存为图片&#xff0c;并且下载到手机上。 说实话网上找了很多资料&#xff0c;但是效果不理想&#xff0c;直到看了一个开源项目&#xff0c;我知道可以实现了。 本文以开源项目uniapp-wxml-to-can…