linux内存监控脚本linux内存监控

如题所述

linux查看cpu占用率最高的程序?

在所有监控Linux系统性能的工具中,Linux的top命令是最好的也是最知名的一个。

top命令提供了Linux系统运行中的进程的动态实时视图。

它能显示系统的概览信息和Linux内核当前管理的进程列表。它显示了大量的系统信息,如CPU使用、内存使用、交换内存、运行的进程数、目前系统开机时间、系统负载、缓冲区大小、缓存大小、进程PID等等。

默认情况下,top命令的输出结果按CPU占用进行排序,每5秒中更新一次结果。如果你想要一个更清晰的视图来更深入的分析结果,以批处理模式运行top命令是最好的方法。

同时,你需要理解top命令输出结果的含义,这样才能解决系统的性能问题。

如何在linux下检测内存泄漏?

要想检测内存泄漏,就必须对程序中的内存分配和释放情况进行记录,所能够采取的办法就是重载所有形式的operatornew和operatordelete,截获newoperator和deleteoperator执行过程中的内存操作信息。下面列出的就是重载形式

void*operatornew(size_tnSize,char*pszFileName,intnLineNum)

void*operatornew(size_tnSize,char*pszFileName,intnLineNum)

voidoperatordelete(void*ptr)

voidoperatordelete(void*ptr)

我们为operatornew定义了一个新的版本,除了必须的size_tnSize参数外,还增加了文件名和行号,这里的文件名和行号就是这次newoperator操作符被调用时所在的文件名和行号,这个信息将在发现内存泄漏时输出,以帮助用户定位泄漏具体位置。对于operatordelete,因为无法为之定义新的版本,我们直接覆盖了全局的operatordelete的两个版本。

在重载的operatornew函数版本中,我们将调用全局的operatornew的相应的版本并将相应的size_t参数传入,而后,我们将全局operatornew返回的指针值以及该次分配所在的文件名和行号信息记录下来,这里所采用的数据结构是一个STL的map,以指针值为key值。当operatordelete被调用时,如果调用方式正确的话(调用方式不正确的情况将在后面详细描述),我们就能以传入的指针值在map中找到相应的数据项并将之删除,而后调用free将指针所指向的内存块释放。当程序退出的时候,map中的剩余的数据项就是我们企图检测的内存泄漏信息--已经在堆上分配但是尚未释放的分配信息。

以上就是内存检测实现的基本原理,现在还有两个基本问题没有解决:

1) 如何取得内存分配代码所在的文件名和行号,并让newoperator将之传递给我们重载的operatornew。

2) 我们何时创建用于存储内存数据的map数据结构,如何管理,何时打印内存泄漏信息。

先解决问题1。首先我们可以利用C的预编译宏__FILE__和__LINE__,这两个宏将在编译时在指定位置展开为该文件的文件名和该行的行号。而后我们需要将缺省的全局newoperator替换为我们自定义的能够传入文件名和行号的版本,我们在子系统头文件MemRecord.h中定义:

#defineDEBUG_NEWnew(__FILE__,__LINE__)

而后在所有需要使用内存检测的客户程序的所有的cpp文件的开头加入

#include"MemRecord.h"

#definenewDEBUG_NEW

就可以将客户源文件中的对于全局缺省的newoperator的调用替换为new(__FILE__,__LINE__)调用,而该形式的newoperator将调用我们的operatornew(size_tnSize,char*pszFileName,intnLineNum),其中nSize是由newoperator计算并传入的,而new调用点的文件名和行号是由我们自定义版本的newoperator传入的。我们建议在所有用户自己的源代码文件中都加入上述宏,如果有的文件中使用内存检测子系统而有的没有,则子系统将可能因无法监控整个系统而输出一些泄漏警告。

再说第二个问题。我们用于管理客户信息的这个map必须在客户程序第一次调用newoperator或者deleteoperator之前被创建,而且在最后一个newoperator和deleteoperator调用之后进行泄漏信息的打印,也就是说它需要先于客户程序而出生,而在客户程序退出之后进行分析。能够包容客户程序生命周期的确有一人--全局对象(appMemory)。我们可以设计一个类来封装这个map以及这对它的插入删除操作,然后构造这个类的一个全局对象(appMemory),在全局对象(appMemory)的构造函数中创建并初始化这个数据结构,而在其析构函数中对数据结构中剩余数据进行分析和输出。Operatornew中将调用这个全局对象(appMemory)的insert接口将指针、文件名、行号、内存块大小等信息以指针值为key记录到map中,在operatordelete中调用erase接口将对应指针值的map中的数据项删除,注意不要忘了对map的访问需要进行互斥同步,因为同一时间可能会有多个线程进行堆上的内存操作。

好啦,内存检测的基本功能已经具备了。但是不要忘了,我们为了检测内存泄漏,在全局的operatornew增加了一层间接性,同时为了保证对数据结构的安全访问增加了互斥,这些都会降低程序运行的效率。因此我们需要让用户能够方便的enable和disable这个内存检测功能,毕竟内存泄漏的检测应该在程序的调试和测试阶段完成。我们可以使用条件编译的特性,在用户被检测文件中使用如下宏定义:

#include"MemRecord.h"

#ifdefined(MEM_DEBUG)

#definenewDEBUG_NEW

#endif

当用户需要使用内存检测时,可以使用如下命令对被检测文件进行编译

g++-c-DMEM_DEBUGxxxxxx.cpp

就可以enable内存检测功能,而用户程序正式发布时,可以去掉-DMEM_DEBUG编译开关来disable内存检测功能,消除内存检测带来的效率影响。

温馨提示:答案为网友推荐,仅供参考
相似回答