前言
内存泄漏和内存对齐
一. 什么是内存泄漏
内存泄漏,是指在程序代码中动态申请的、堆上的内存 由于某种原因、在使用后没有被释放,进而造成内存的浪费。
少部分的内存泄漏不会影响程序的正常运行,不过如果是持续的内存泄漏会耗光系统内存,最终会导致程序卡死甚至系统崩溃。为了避免系统崩溃,在无法申请到内存的时候,要果断调用exit()函数主动杀死进程,而不是试图挽救这个进程。
二.内存泄漏常见的几种原因
1.堆内存泄漏:new/mallc分配内存,未使用对应的delete/free回收
2.系统资源泄漏, Bitmap, handle,socket等资源未释放
3.没有将基类析构函数定义称为虚函数,(使用基类指针或者引用指向派生类对象时)派生类对象释放时将不能正确释放派生对象部分
三.如何避免内存泄漏
1、不要手动管理内存,可以尝试在适用的情况下使用智能指针。
2、使用string而不是char*。string类在内部处理所有内存管理,而且它速度快且优化得很好。
3、除非要用旧的lib接口,否则不要使用原始指针。
4、在C++中避免内存泄漏的最好方法是尽可能少地在程序级别上进行new和delete调用–最好是没有。任何需要动态内存的东西都应该隐藏在一个RAII对象中,当它超出范围时释放内存。RAII在构造函数中分配内存并在析构函数中释放内存,这样当变量离开当前范围时,内存就可以被释放。
(注:RAII资源获取即初始化,也就是说在构造函数中申请分配资源,在析构函数中释放资源)
5、使用了内存分配的函数,要记得使用其想用的函数释放掉内存。可以始终在new和delete之间编写代码,通过new关键字分配内存,通过delete关键字取消分配内存。
四.被释放掉的内存会立即被系统回收吗
不是的,被free掉的内存首先会被ptmalloc使用双链表保存起来,当用户下一次进行申请的时候,会尝试在这些中找到合适的内存进行返回,这样避免了系统的频繁调用,占用过多的资源,同时ptmalloc也会尝试对小内存进行合并,避免过多的内存碎片。
五.为什么要内存对齐
数据结构( 尤其是栈 ) 应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。这里归根结底的来说就是以 空间换时间 。
平台原因:不是所有的硬件平台都能访问任意内存地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。为了同一个程序可以在多平台运行,需要内存对齐。
性能原因:内存对齐能够提高内存访问效率。CPU 在读取内存时,一次读取固定长度的数据(如4字节、8字节等)。如果将多个变量连续分配在内存中而不做对齐处理,会造成 CPU 读取数据出现“半包”的情况,此时,需要再进行一次内存访问才能获取该变量数据。
总结
详细理解内存泄漏和为什么要内存对齐