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.rhkb.cn/news/162110.html

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

相关文章

centos 7.9 源码安装htop

1.下载源码 wget http://sourceforge.net/projects/htop/files/latest/download 2.上传到tmp目录,并解压 tar xvzf htop-1.0.2.tar.gz mv htop-1.0.2 /opt/ 进入到 cd /opt/htop-1.0.2/ 3.编译并安装 ./configure && make && make install 4.…

基于混沌博弈优化的BP神经网络(分类应用) - 附代码

基于混沌博弈优化的BP神经网络(分类应用) - 附代码 文章目录 基于混沌博弈优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.混沌博弈优化BP神经网络3.1 BP神经网络参数设置3.2 混沌博弈算法应用 4.测试结果…

什么是CSGO大行动,2023年CSGO大行动时间预测

什么是CSGO大行动,2023年CSGO大行动时间预测 什么是CSGO大行动,2023年CSGO大行动时间预测 那天群里在提大行动,不明所以的新同学在问,什么是大行动,是不是官方红锁大行动要来了?当然不是,别自己…

Linux内核的.config 配置文件和defconfig 配置文件

Linux 内核可以通过输入“make menuconfig”来打开图形化配置界面,menuconfig 是一套图形化的配置工具 一、图形化界面的操作 menuconfig 图形化的配置工具需要 ncurses 库支持。ncurses 库提供了一系列的 API 函数供调用者生成基于文本的图形界面,因此…

c++_learning-基础部分

文章目录 基础认识:语言特性(面向对象编程):c的类(相当于c中的结构体):三大特性:c包含四种编程范式:优缺点: c程序编译的过程:预处理->编译&am…

《软件方法》第1章2023版连载(07)UML的历史和现状

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 1.3 统一建模语言UML 1.3.1 UML的历史和现状 上一节阐述了A→B→C→D的推导是不可避免的,但具体如何推导,有各种不同的做法,这些做法可以称为“方…

WebDAV之π-Disk派盘 + 密码键盘

密码键盘是一款密码管理器,可以存储和管理需要受保护的数据。为方便日常使用,同时也是一款安全输入法,帮您安全便捷地填写账号密码、通用内容、卡包信息。 密码键盘使用军事级的 PBKDF2 有损加密算法保护您的根密码,使用军事级的 AES 加密算法保护您的存储数据。云端再额外…

VBA之正则表达式(43)-- 从网页中提取指定数据

实例需求:由网页中提取下图中颜色标记部分内容,网页中其他部分与此三行格式相同。 方法1 Sub Demo()Dim objRegex As ObjectDim inputString As StringDim objMatches As ObjectDim objMatch As ObjectSet objRegex CreateObject("VBScript.RegEx…

为什么不可大张旗鼓地推动“汉字编程”?

为什么不可大张旗鼓地推动“汉字编程”? 没有不可。 我之前看到过一个vscode插件,是给一个不知道叫什么名字的编程语言用的,从代码到注释全是西里尔字母写的,反正就只有东欧那片区域用。最近很多小伙伴找我,说想要一些…

2023年中国自动驾驶卡车市场发展趋势分析:自动驾驶渗透率快速增长[图]

自动驾驶卡车的技术原理是通过电脑算法控制车辆行驶,辅助驾驶员完成任务。其实现方式主要是基于传感器和计算处理技术。自动驾驶卡车可以随时感知周围环境,灵活避障,自适应调整行驶路径,相比之下传统卡车需要驾驶员进行手动操作&a…

使用postman做接口测试

1.接口测试:针对软件对外提供服务的接口的输入输出进行测试,以及接口间相互逻辑的测试,验证接口功能与接口描述文档的一致性 2.接口测试流程: 1)获取接口信息:通过接口文档或抓包来获取接口的基本调用方式和…

C# 取消一个不带CancellationToken的任务?

在异步函数中&#xff0c;一般使用CancellationToken来控制函数的执行。这个Token需要作为参数传递到异步函数中&#xff1a; public staic Task<T> DoAsync(CancellationToken token) {... } 那么如果一个异步函数没有这个Token参数&#xff0c;如何取消呢? 之前看到一…

Dasviewer浏览器里显示模型裁剪不成功,输出无数据是什么原因?

答&#xff1a;Metadata文件需要先放在Terraosgb文件夹瓦块再试试 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便快捷的数据浏览操作。#DasViewer##…

JAVA基础(JAVA SE)学习笔记(三)流程控制语句

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 正文 JAVA基础&#xff08;JAVA SE&#xff09;学习笔记&#xff08;一&#xff09;JAVA学习路线、行业了解、…

git 使用

参考 https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%8E%B7%E5%8F%96-Git-%E4%BB%93%E5%BA%93 文件的状态变化周期 文章目录 git 基础检查当前文件状态、查看已暂存和未暂存的修改暂存前后的变化跟踪新文件提交更新移除文件移动文件、重命名操作查看提交历史撤消…

企业c#语言源代码防泄密解决方案

在当今数字化时代&#xff0c;企业的核心业务往往依赖于软件应用程序。为了保护企业的知识产权和敏感信息&#xff0c;源代码的保密至关重要。对于制造类企业尤其是智能制造业来讲&#xff0c;最近几年是高速发展的时期&#xff0c;很多公司在做工厂流水线设备时&#xff0c;就…

Redis分布式锁

目录 ​编辑Redis实现全局唯一Id 测试类 关于countdownlatch 添加优惠卷 实现秒杀下单 库存超卖问题分析 优惠券秒杀-一人一单 ​编辑 分布式锁 基本原理和实现方式对比 Redis分布式锁的实现核心思路 实现分布式锁版本一 Redis分布式锁误删情况说明 解决Redis分布式…

安防视频监控平台EasyCVR出现视频流播放卡顿情况,如何优化?

视频集中存储/云存储/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。AI智能/大数据视频分析EasyCVR平台已经广泛应用在工地、工厂、园区、楼…

超细致的性能测试流程,你get了吗?

性能测试&#xff1a;利用工具模拟大量用户操作&#xff0c;验证系统承受的负载情况。 性能测试的目的&#xff1a;找到潜在的性能问题或瓶颈&#xff0c;分析并解决&#xff1b;找出性能变化趋势&#xff0c;为后续扩展系统提供参考。测试监控&#xff1a;基准测试、配置测试…

【嵌入式开发问答】不是普通的嵌入式八股

1. 进程、线程、堆栈、溢出 【问&#xff1a;】 进程的堆栈的物理内存是什么时候分配的&#xff1f; 堆栈的大小限制是多大&#xff1f;这个限制可以调整吗&#xff1f; 当堆栈发生溢出后应用程序会发生什么&#xff1f; 【答&#xff1a;】