关于vector的内存管理策略

 

问题:
我在程序中clear一个很大的vector 它所占用的内存不能全部的释放, 再次向vector中插入大量数据,再次clear 它还是占用那么大的内存.
就是说一个大的vector始终占用了一定量的内存 clear或者和一个空vector交换后内存没有完全释放,而要到关闭程序后才释放?
有什么方法可以释放掉vector中占用的全部内存呢? 
回答:
///
再次clear 它还是占用那么大的内存.
=================
这个倒不一定,举个例的说明,
假设编译器默认的capacity为10,当你插入11个元素的时候,编译器把capacity设置为20(一般的编译器都翻倍处理),这时你的vector占20个元素的内存,这时你clear,把数据清了,vector为空了,capacity又变成了默认值的10,即这时占10个元素的内存了

///
标准的解决方法如下
template < class T >
void ClearVector( vector< T >& vt )
{
vector< T > vtTemp;
veTemp.swap( vt );
}

//
为什么似乎所有的人都认为vector的内存管理直接对应操作系统的内存管理?
一个vector删除了元素,内存就未必马上归还给操作系统吗?关键看系统和库的管理策略,完全可能程序仍然保留着那块内存,必要时给同一进程中的其它动态申请使用。
而且,在这个问题上,不同的操作系统平台上,不同的编译器中,策略不尽相同?
当然,大多数情况下会跟一次性申请/释放的数量有关系。

偶承认偶没看过《STL源码剖析》,但关键问题是,在大多数情况下,这个问题不是STL的实现者自已能说得算的问题。vector即使保证把底层占用的内存“释放”了,也并不意味着程序就立即归还给操作系统了,vector只是程序中某处的一个对象,它不用了不代表程序也不用了。

从应用程序的级别,用swap也差不多了。
如果swap之后从任务管理器中观察到有效果,那当然最好不过;如果没有效果,那也只能认了。
再要往下追,不是没意义,但至少是超出C++程序设计的层面和角度了,我觉得。

//
SGI的stl不存在类似gc的功能:

事实上,vector根本就不管内存,它只是负责向内存管理框架acquire/release内存,内存管理框架如果发现内存不够了,就malloc,但是当vector释放资源的时候(比如destruct), stl根本就不调用free以减少内存,因为内存分配在stl的底层:stl假定如果你需要更多的资源就代表你以后也可能需要这么多资源(你的list, hashmap也是用这些内存),所以就没必要不停地malloc/free。 如果是这个逻辑的话这可能是个trade-off

至于应用层面可以显示地告知内存管理框架说我现在不用了,你释放一些吧,也还算合理:
   vector<T> vworking;
   {
      vector<T> vupdating = vworking;
      // 这里vupdating申请的内存(拷贝)永远不会被释放
      // 这在vworking的内容很大时候会很糟糕
   }
 所以stl可以有一个这样的tricky:shrink to fit,也就是上面的swap
其实我觉得stl应该有一个标准的方法来shrink to fit
同意stl是最优秀的代码之一,值得学习。

///
"Michael Andersson" <a98mi...@ida.his.se> wrote in message


news:3ECA8B4A.4020204@ida.his.se...

> Does the STL specification say anything about whether or not
> vector::clear will release allocated memory when called? Or is this only
> performed when reserve is called with a value less than capacity?


None of these will.

The common idiom to clear a vector and release the memory it allocated
is:
      vector<TheItemType>().swap( theVectorToClear ); 
      This creates an empty temporary vector and swaps its contents with
those of the provided variable. The destructor of the temporary
will then typically release memory previously associated with
the variable.
     It is not formally guaranteed to work -- but in practice it does.
(and because it has become a common C++ idiom, I do not think that
 a library implementer would want to provide a different behavior).
hth,
--
 Ivan Vecerina, Dr. med.  <>  http://www.post1.com/~ivec
 Soft Dev Manger, XiTact  <>  http://www.xitact.com
 Brainbench MVP for C++   <>  http://www.brainbench.com

//
一般的STL内存管理器allocator都是用内存池来管理内存的,所以某个容器申请内存或释放内存都只是影响到内存池的剩余内存量,而不是真的把内存归还给系统。这样做一是为了避免内存碎片,二是提高了内存申请和释放的效率——不用每次都在系统内存里寻找一番。
真的让容器把不用的内存归还给系统的话,楼主只能自己写一个allocator,并在容器的模板参数里使用它,而且STL的标准容器确实都留了这个接口。
不过楼主要意识到这样做给程序性能和系统内存带来的影响。


clear和erase可以很好地减少了vector的大小(size),但没有减少它的容量(capactiy)
vector<T>(v).swap(v);
// 使用“交换技巧”来修整过剩容量
这种方式使vector的size == capactiy

STL中的内存分配一般采用内存池策略,如果单纯的通过任务管理察看应用程序的
使用量,发现当使用stl库的vector或者其他容器进行清空数据后,内存变化显著,反而
不能使用,因为这时STL库在内存上没有做优化。

上面有两本书《effective STL》,《深入剖析STL》值得一读

///
哇 好多回帖阿 感谢感谢 学习ing

这个是不是和编译器有关系呢
我用的是C++ buidler
我是在程序中使用了swap,单步跟踪程序并查看任务管理器,执行过swap时内存没有动静,capacity()返回的值为0,但是占用的内存没有释放掉,只有在函数结束,也就是在vector的生命结束时 才释放了一小部分 还有一大部分vector占用的没有释放,再次在别的按钮事件中用同样的代码,这部分没有释放的内存一直就是被vector使用了,不回归了,而且vector越大占用的越大。 哈哈~~
刚才用vc7.1试了一下 结果完全不同, 执行到clear()或者swap时候内存全释放了,capacity()返回的值也为0了,连clear()方法也一样,也修改了capacity的值;
我晕了~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值