5.2 C++11堆内存管理:智能指针与垃圾回收

一、显示内存管理

对于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++一些垃圾回收的库,但是由于指针的灵活性(指针可能做了移动,但是原来的内存并不一定被释放,可能还会移回继续使用原来的内存),所以只是最小垃圾回收支持。

你可能感兴趣的:(深入理解C++11新特性,C++11)