最近测试中,我们的系统在多线程高并发访问的情况下,内存开始逐渐增长,到一定值以后,即使所有的连接线程都退出,常驻内存也不释放,经过仔细的检查分析,内置的内存资源池都正确释放,而且在连接活跃时,常驻内存在到达一定值后也会保持一个平稳水平,可以排除是我们系统代码的问题,这里可以通过一个简单的程序抛开无关的部分再现系统的内存占用问题。
#include<stdio.h> #include<stdlib.h> #include<pthread.h> #include<errno.h> #include<unistd.h> #include<memory.h> #include <libpq-fe.h> #define THREAD_NUM 5 void* thread_malloc(void*); int main(int argc, char** argv) { pthread_t tid[THREAD_NUM]; int err, i, j = 10, pid; pid = getpid(); printf("pid = %d ", pid); sleep(20); while( j-- > 0) { for(i=0; i<THREAD_NUM; i++){ err = pthread_create(&tid[i], NULL, thread_malloc, NULL); if (err !=0) printf("%s: %d ",__func__, strerror(err)); } for(i=0; i<THREAD_NUM; i++){ pthread_join(tid[i], NULL); } } printf("All thread finish "); sleep(15);
return 0; } void *thread_malloc(void *arg) { char *buf =NULL; int i; buf = (char *) malloc(1024*sizeof(char)); for (i=0; i< 1024; i++){ buf[i] = 'x'; } printf("allocate 1024 bytes "); sleep(2); free(buf); }
线程启动前的内存使用情况:
线程退出后的内存使用情况:常驻内存并没随线程退出释放
valgrind进行检查的结果:不存在内存泄露
关于这个问题的详细原因,经多方查证问题出在glibc库的malloc上,通过glibc分配内存时,glibc有自己的内存管理机制,并不会将这部分内存马上归还给OS,这里推荐淘宝华庭的《glibc内存管理-ptmalloc2源代码分析》,里面对ptmalloc的分配原理从代码层给出了详细的分析,通过这个问题也让我感觉到,很难有一种内存管理方法适用于所有场景,为了让内存管理更有效率,应用系统本身的内存管理机制要与库提供的内存管理机制进行调试,必要的场合使用系统调用直接分配内存。