【发布时间】:2011-12-29 17:24:48
【问题描述】:
在 OS X Snow Leopard 下开发 32 位 C++/carbon 应用程序时遇到了一个问题,即大约 20,000 个小对象(每个 72 字节)的 stl 向量在重新分配期间失败。看起来这个大小为几兆字节的向量无法扩展为一块连续的内存,在发生故障时它只有 1.2 MB 大小。
GuardMalloc[Appname-33692]: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
GuardMalloc[Appname-35026]: Failed to VM allocate 894752 bytes
GuardMalloc[ Appname-35026]: Explicitly trapping into debugger!!!
#0 0x00a30da8 in GMmalloc_zone_malloc_internal
#1 0x00a31710 in GMmalloc
#2 0x94a54617 in operator new
#3 0x0026f1d3 in __gnu_cxx::new_allocator<DataRecord>::allocate at new_allocator.h:88
#4 0x0026f1f8 in std::_Vector_base<DataRecord, std::allocator<DataRecord> >::_M_allocate at stl_vector.h:117
#5 0x0026f373 in std::vector<DataRecord, std::allocator<DataRecord> >::_M_insert_aux at vector.tcc:275
#6 0x0026f5a6 in std::vector<DataRecord, std::allocator<DataRecord> >::push_back at stl_vector.h:610
我能想到几个策略:
1) Reserve() 是一个非常非常大的向量,一旦应用程序启动。但是,这假设用户可能不会加载有助于该向量的其他文件,从而将其推到超出预先分配的限制并可能回到相同的情况。
2) 将对象/内存分配的向量更改为指向对象/内存分配的指针向量。显然使向量本身的大小更易于管理,但随后会创建 20,000 个小对象(最终可能会变成 50,000 个对象,具体取决于用户加载的其他文件)。这会产生巨大的开销问题吗?
3) 从向量变为列表,这可能有其自身的开销问题。
向量不断迭代,通常只附加到。
对这些问题有什么明智的想法吗?
================
附加说明:此特定向量仅包含所有导入的记录,因此它们可以通过包含排序顺序的另一个向量进行索引和排序。将项目放入此向量后,它会在应用程序的整个生命周期内一直存在(还有助于支持撤消操作,确保向量中的索引对于该特定对象始终保持不变)。
【问题讨论】:
-
任何让它成为 64 位应用程序的机会 - Carbon 已贬值,因此您需要在合理的短时间内进行更改。
-
@Mark:你的意思是“弃用”吗?我想碳也在贬值。
-
你能把向量拆分成多个向量吗?
vector<vector<A>*> VoV[100];填充Vov[0],push_back失败。开始填写VoV[1]。等等。这合适吗?或者处理多个结构中的数据(排序、搜索……)的工作量太大。顺便说一句,您可以创建自己的函数来这样做......我太乐观了 -
@outis - 不,不是!你看到汽油的价格了吗?
-
@user516545(您可能想选择一个有意义的名称):对集合的各种操作(例如添加、删除、随机访问、迭代)的相关重要性是什么?对象是否有自然排序?多一点 background detail 会有所帮助。
标签: c++ macos optimization memory-management stl