一、显示内存管理
对于C++的显示内存管理,常见的问题:
1.野指针。指针未初始化、指针溢出、内存已经释放的指针
2.重复释放。即多个指针指向同一片区域,导致重复释放。
3.内存泄漏。指针指向的内存释放之前,先释放了指针,导致那块内存无法访问,且无法重新使用。
二、智能指针
原有auto_ptr被弃用。而是引入unique_ptr、shared_ptr、weak_ptr三个智能指针。
参见C++11 智能指针 · 语雀 《C++11 智能指针》
三、垃圾回收的分类
垃圾:不再使用或者没有任何指针指向的内存称为垃圾。
垃圾回收:将垃圾收集起来重新利用,叫做垃圾回收。
1.基于计数:
通过引用计数的方式,每有一个指针引用此内存时,计数+1,相反,每有一个指针不再引用此内存时,计数-1。当计数为0时,表示没有对象引用资源,则进行释放。值得注意的时引用计数类型都存在环形引用的问题。
此方式的优点是实现简单、副作用小、不需要额外的交换空间等,缺点是环形引用问题比较难处理。
2.基于跟踪处理:
基本原理是跟踪对象关系、然后进行垃圾回收。
2.1标记-清除
第一步先以当前对象为"根对象",然后对其引用的堆空间进行逐层标记,而未标记上的内存则认为是垃圾,第二步则是对垃圾进行回收。
优点是活的对象对象不会移动,但是会存在很多碎片
2.2标记-整理
第一步扫描,第二步则是向左靠齐,这样不会有内存碎片,但是所有的堆内存引用都需要重新赋值。
2.3标记-拷贝
第一步扫描,第二步移动,移动的方式是将空间分成from和to两部分,将当前活的对象坐在区域为from,然后移动到to空间内,然后将from空间清空,并将from和to的定义互换。
缺点是空间利用率只有一半
四、C++与垃圾回收
C++一些垃圾回收的库,但是由于指针的灵活性(指针可能做了移动,但是原来的内存并不一定被释放,可能还会移回继续使用原来的内存),所以只是最小垃圾回收支持。