Linux内存泄漏与测试
今天在接口压力测试过程中发现在反复调用接口某一段时间后, 系统无法正常响应请求,一段时间后又恢复正常,查看Log时发现,在出现系统无法正常响应接口请求时,会kill掉特定的两个进程,因此判断这两个进程在系统运行一段时间后,始终为系统占用内存最多的两个进程,怀疑这两个进程存在内存泄漏。于是写了一个shell小脚本每隔一段时间打印这两个进程所占用的物理内存,具体的shell脚本为while true;do cat/proc/{进程PID/status |grep VmRSS;sleep 1;done},果然发现这两个进程所占用的物理内存存在稳定性增长的现象,存在着内存泄漏,于是觉得有必要总结一下什么是内存泄漏,如何测试内存泄漏,内存泄漏是如何产生的以及怎样解决内存泄漏。
什么是内存泄漏
内存泄漏是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
内存泄漏是如何产生的
内存泄漏是C编程中最常见的问题,在C语言上,从变量存在的生命周期角度,把变量分为静态存储变量和动态存储变量两类,静态存储变量会在程序运行过程中被分配固定存储空间,在程序结束时会释放,而动态存储变量则是在程序执行过程中根据需要动态分配和释放的存储单元。程序中动态分配的存储空间,在程序执行完毕后需要释放。没有释放动态分配的存储空间就会造成内存泄漏。
如何测试是否有内存泄漏
(1) 在压力测试过程中,我们主要倾向于模仿用户长时间使用设备或调用接口,经过一段时间后,查看进程内存的使用情况,对于那些内存大量增长的进程,可以初步怀疑有内存泄漏发生。这种测试的好处是测试成本比较低,比较贴近用户真实使用场景,然而往往可能出现我们并不知道具体有哪些进程存在内存泄漏,导致开发修改了一处之后可能会有遗漏,这样反复测,反复修改,拖慢了整个项目周期。
(2) 单独针对某个进程进行压力测试,比较反复调用进程前后内存的使用情况,这种测试的好处在于测试能够全面了解具体是哪些进程存在内存泄漏,而缺点在于测试的工作量过于庞大。
因此,我觉得抓住问题大概率出现的系统进程进行单独压测,最后再与其他进程进行全面压测是更好的办法,因此我们有必要了解在Linux系统中具体是哪些进程会大概率出现内存泄漏的现象。对于我所从事的通信行业来讲,大部分产品都是以linux为内核的嵌入式产品,产品中的各功能模块都是在系统中安装某种服务来提供的,比如netifd,一个管理网络接口和路由功能的后台进程,这种需要为用户吃持续长时间提供服务的进程叫做守护进程,又被称为精灵进程,内存泄漏就大概率地存在于守护进程中,因此这些进程应该是我们需要主要关注的进程。
关于内存泄漏的测试方法,不知道其他同学有没有这方面的经验或者有更好的测试方法,希望能不吝赐教。