内存碎片:
什么是内存碎片:
已经释放了使用的权的内存,但无法被malloc再次分配出去,这种内存叫内存碎片。
int* p1 = malloc(4); int* p2 = malloc(4); int* p3 = malloc(4); free(p2); // 此时p2已经被释放,但无法再次分配给p4,p2就是内存碎片,如果后续不再分配较小的内存块,p2可能一直接内存碎片 int* p4 = malloc(16); // 此时p2就有可能被再次分配出来,它就不是内存碎片, int* p5 = malloc(4); // 如果p1或p3被释放,p2就不是内存碎片了 free(p1); free(p3);
内存碎片产生的原因:
内存和释放、分配时间、大小不协调导致的。
一块内存碎片,只是短时间内是碎片,过一段时间它可能就不是碎片了,所以内存碎片不是绝对的。
如何减少内存碎片:
前提:内存碎片只能尽量减少,无法杜绝。
1、尽量使用栈内存(要了解栈内存的特性,要知道栈内存的使用上限,ulimit -s 、ulimit -s <size>)。
2、尽量分配大块内存自己管理。
int* p1 = malloc(16); int* p2 = p1+1; int* p3 = p1+2; int* p4 = p1+3;3、按照分配的顺序,逆序释放,把堆内存当栈进行管理。
int* p1 = malloc(4); int* p2 = malloc(4); int* p3 = malloc(4); int* p4 = malloc(4); free(p4); free(p3); free(p2); free(p1);4、内存碎片整理
int* p1 = malloc(4); int* p2 = malloc(4); int* p3 = malloc(4); memcpy(p2,p3,4); swap(p2,p3); free(p2);
内存泄漏:
什么是内存泄漏:
内存已经不再使用,但无法被释放的内存叫内存泄漏。
但这不是最严重的,严重的是反复的内存泄漏,例如:一个函数执行需要分配一块堆内存,等它执行完毕后堆内存没有被释放,等再次调用这个函数时,它又重新分配堆内存,又没有释放,反复这样会导致可用的内存越来越少,系统、程序会变得越来越慢、卡、死机。
void func(void) { int* p = malloc(40); for(int i=0; i<10; i++) { p[i] = rand() % 100; printf("%d ",p[i]); if(条件) return; } printf("\n"); free(p); } int main() { for(;;) { ... func(); ... } }
产生内存泄漏的原因:
1、只写的内存分配语句,而忘记写内存释放语句,可能是粗心大意,也可能是以为别人会释放。
2、写了内存释放语句,但由于执行流程、执行条件设计有问题,导致释放语句没有执行。
3、与堆内存配合的指针被破坏,改变了指向,导致free语句执行无效。
如何减少内存泄漏:
1、按规则分配、释放内存:
自用:谁申请谁释放,分配语句和释放语句成对出现。
共用:谁知道该释放谁释放,项目组中负责分配和负责释放的人要进行对接。
2、封装malloc和free函数,记录每一次的分配和释放的内存块地址,通过对比记录,就可以发现是否有内存泄漏。
void my_free(void* ptr) { printf("free %p\n",ptr); free(ptr); } void* my_malloc(size_t size) { void* ptr = malloc(size); printf("malloc %p\n",ptr); return ptr; }3、使用const保护与堆内存配合的指针变量,防止指针被破坏。
int* const p = malloc(4); p = # // 编译会出错 free(p); // 此时释放的肯定是堆内存
检查内存泄漏的工具:
# 安装该工具的命令 sudo apt install valgrind #使用该工具检测程序: valgrind --tool=memcheck --leak-check=yes ./a.out
内存泄漏和内存碎片的危害:
前提:当程序结束时,操作系统会把分配它的所有资源全部回收(包括系统分配给程序的堆内存),所以当程序结束时,内存碎片和内存泄漏就会消失,这也是为什么软件、系统重启能解决很多问题。
注意:服务器端的程序一般需要7*24小时运行,不能随意结束。
客户端的程序可以随意的关闭、重启系统和软件,所以即使发生内存碎片和内存泄漏,也问题不大,但如果是服务端的程序,即使只有少量的内存泄漏和内存碎片,长年累月下来也会导致系统可用的内存越来越少,系统、程序会变得越来越慢、卡、死机。