内存泄露的排查与定位
- 栈内存由系统自动分配和管理。一旦程序运行超出了这个局部变量的作用域,栈内存就会被系统自动回收,所以不会产生内存泄露的问题
- 堆内存由应用程序自己来分配和管理。除非程序退出,这些堆内存并不会被系统自动释放,而是需要应用程序明确调用库函数 free 来释放他们。如果程序没有正确释放堆内存,就会造成内存泄露
- 只读段,包括程序的代码和常量,由于是只读的,不会再去分配新的内存,所以也不会产生内存泄漏
- 数据段,包括全局变量和静态变量,这些变量在定义时就已经确定了大小,所以也不会产生内存泄漏
- 最后一个内存映射段,包括动态链接库和共享内存,其中共享内存由程序动态分配和管理。所以,如果程序在分配后忘了回收,就会导致跟堆内存类似的泄漏问题
内存泄漏的危害非常大,这些忘记释放的内存,不仅应用程序自己不能访问,系统也不能把它们再次分配给其他应用。内存泄漏不断累积,甚至会耗尽系统内存。
虽然,系统最终可以通过 OOM (Out of Memory)机制杀死进程,但进程在 OOM 前,可能已经引发了一连串的反应,导致严重的性能问题;比如,其他需要内存的进程,可能无法分配新的内存;内存不足,又会触发系统的缓存回收以及 SWAP 机制,从而进一步导致 I/O 的性能问题等等。如下详细的说明:
当进程发生内存泄漏导致OOM(Out of Memory)时,内核会尝试杀死一些进程以释放内存。在被杀死之前,OOM进程会尝试使用系统资源来满足其内存需求,这可能会导致系统整体变慢,直至崩溃。具体来说,以下是可能导致系统变卡的原因:
系统交换
当系统内存不足时,内核会尝试将一些不常用的内存页面移到交换分区中,以腾出物理内存。但是,交换分区通常比物理内存慢得多,因此如果内存压力持续较长时间,交换操作可能会导致系统整体变慢
I/O阻塞
当系统内存不足时,内核可能会开始进行页面回收,即将不活跃的内存页面写回到磁盘上,以腾出物理内存。这可能导致系统磁盘I/O负载增加,进而导致磁盘I/O阻塞。如果磁盘I/O阻塞过长时间,可能会导致系统整体变慢。
CPU利用率上升
当内存压力较大时,内核可能会频繁地进行页面回收和交换操作,这可能导致CPU利用率上升。同时,当进程使用过多的内存时,可能会导致进程频繁地进行内存分配和释放操作,这也可能导致CPU利用率上升。如果CPU利用率过高,可能会导致系统整体变慢。
内存分配器性能下降
当进程频繁地进行内存分配和释放操作时,可能会导致内存分配器出现性能问题。如果内存分配器的性能下降,可能会导致进程内部的性能下降,从而影响系统整体性能。
综上所述,当进程发生内存泄漏导致OOM时,系统整体变卡的原因是多方面的,包括系统交换、I/O阻塞、CPU利用率上升以及内存分配器性能下降等。
一、场景
memleak 是 bcc 软件包中的一个工具。另一个用的比较多的是valgrind。