http://blog.csdn.net/gamecreating/article/details/7698719
http://blog.csdn.net/zunceng/article/details/7742788
今天记录一下长久以来屡次犯的错,每次都是换一种方法编码来绕过这个问题实现功能的,因为这个问题太过隐蔽,导致今天才发现其中真正的原因...下面进行问题描述:
1std::map<std::string, Value> keyValue; // 在函数内部分配的堆栈对象(局部变量)
2ReadData(keyValue);// 从dll中导出的函数
3keyValue.clear(); // delete中出现assert异常
第一行是在应用程序中的堆栈中分配的内存空间。
第二行是我自己写的dll库,用来读取一些数据加入到keyValue中。
第三行是清空keyValue,其实如果不写这一行的话,keyValue也会在函数结尾时清空,到那时同样会出现错误。
这一切乍一看没啥问题,keyValue是局部变量,为什么局部变量的释放会出现异常错误呢?这是因为第二行ReadData的缘故。ReadData的逻辑在另外一个可执行模块中,在其中分配的内存空间不一定与当前模块在同一个堆区。
我们知道,std::map是一个树结构的容器,我在ReadData内部往keyValue中添加了数据,keyValue中会在堆区中分配树节点,而这个节点将会在当前模块在keyValue的析构中被释放。也就是说,我无意中在dll模块中分配了堆空间,又无意中在exe模块中企图释放该空间,这样的行为导致错误是不足为怪的。
时刻牢记,在一个模块中分配和释放同一块内存区域,警惕你所看不见的内存分配和释放。
概要
本文比较各种内存分配器(Allocator)在用于STL容器上的性能。参与本次比较的Allocator有:
选择的STL容器为map。其他容器如std::list, std::set, std::multi_set, std::multi_map类似。
对比程序
测试方法 - 对比以下四种情况:
- 使用标准的std::map<int, int>。
- 使用ScopeAlloc作为分配器。即std::Map<int, int>。
- 使用AutoFreeAlloc作为分配器。即std::Map<int, int, std::less<int>, std::AutoFreeAlloc>。
- 使用ScopeAlloc作为分配器,且共享同一个std::BlockPool。
测试程序(参见<stdext/Map.h>):
template <class LogT>
class TestMap : public TestCase
{
WINX_TEST_SUITE(TestMap);
WINX_TEST(testCompare);
WINX_TEST_SUITE_END();
public:
enum { N = 20000 };
void doStlMap(LogT& log)
{
typedef std::map<int, int> MapT;
log.print("===== std::map =====\n");
std::PerformanceCounter counter;
{
MapT coll;
for (int i = 0; i < N; ++i)
coll.insert(MapT::value_type(i, i));
}
counter.trace(log);
}
void doMap1(LogT& log)
{
typedef std::Map<int, int, std::less<int>, std::AutoFreeAlloc> MapT;
log.print("===== std::Map (AutoFreeAlloc) =====\n");
std::PerformanceCounter counter;
{
std::AutoFreeAlloc alloc;
MapT coll(alloc);
for (int i = 0; i < N; ++i)
coll.insert(MapT::value_type(i, i));
}
counter.trace(log);
}
void doMap2(LogT& log)
{
typedef std::Map<int, int> MapT;
log.print("===== std::Map (ScopeAlloc) =====\n");
std::PerformanceCounter counter;
{
std::BlockPool recycle;
std::ScopeAlloc alloc(recycle);
MapT coll(alloc);
for (int i = 0; i < N; ++i)
coll.insert(MapT::value_type(i, i));
}
counter.trace(log);
}
void doShareAllocMap(LogT& log)
{
typedef std::Map<int, int> MapT;
std::BlockPool recycle;
log.newline();
for (int i = 0; i < 5; ++i)
{
log.print("===== doShareAllocMap =====\n");
std::PerformanceCounter counter;
{
std::ScopeAlloc alloc(recycle);
MapT coll(alloc);
for (int i = 0; i < N; ++i)
coll.insert(MapT::value_type(i, i));
}
counter.trace(log);
}
}
void testCompare(LogT& log)
{
for (int i = 0; i < 5; ++i)
{
log.newline();
doStlMap(log);
doMap2(log);
doMap1(log);
}
doShareAllocMap(log);
}
};
测试结果
===== std::map =====
---> Elapse 29649998 ticks (8283.18 ms) (0.14 min) ...
===== std::Map (ScopeAlloc) =====
---> Elapse 9045729 ticks (2527.06 ms) (0.04 min) ...
===== std::Map (AutoFreeAlloc) =====
---> Elapse 9683232 ticks (2705.16 ms) (0.05 min) ...
===== std::map =====
---> Elapse 38099194 ticks (10643.59 ms) (0.18 min) ...
===== std::Map (ScopeAlloc) =====
---> Elapse 15013312 ticks (4194.20 ms) (0.07 min) ...
===== std::Map (AutoFreeAlloc) =====
---> Elapse 15039592 ticks (4201.54 ms) (0.07 min) ...
===== std::map =====
---> Elapse 24698608 ticks (6899.93 ms) (0.11 min) ...
===== std::Map (ScopeAlloc) =====
---> Elapse 10867094 ticks (3035.89 ms) (0.05 min) ...
===== std::Map (AutoFreeAlloc) =====
---> Elapse 15611309 ticks (4361.26 ms) (0.07 min) ...
===== std::map =====
---> Elapse 37594376 ticks (10502.56 ms) (0.18 min) ...
===== std::Map (ScopeAlloc) =====
---> Elapse 8846240 ticks (2471.33 ms) (0.04 min) ...
===== std::Map (AutoFreeAlloc) =====
---> Elapse 8667671 ticks (2421.44 ms) (0.04 min) ...
===== std::map =====
---> Elapse 30175306 ticks (8429.93 ms) (0.14 min) ...
===== std::Map (ScopeAlloc) =====
---> Elapse 9033720 ticks (2523.71 ms) (0.04 min) ...
===== std::Map (AutoFreeAlloc) =====
---> Elapse 8723023 ticks (2436.91 ms) (0.04 min) ...
===== doShareAllocMap =====
---> Elapse 8441194 ticks (2358.18 ms) (0.04 min) ...
===== doShareAllocMap =====
---> Elapse 7651772 ticks (2137.64 ms) (0.04 min) ...
===== doShareAllocMap =====
---> Elapse 7900730 ticks (2207.19 ms) (0.04 min) ...
===== doShareAllocMap =====
---> Elapse 7861035 ticks (2196.10 ms) (0.04 min) ...
===== doShareAllocMap =====
---> Elapse 7530844 ticks (2103.86 ms) (0.04 min) ...
测试结论
使用ScopeAlloc或者AutoFreeAlloc后,STL容器的性能有显著提高。而ScopeAlloc与AutoFreeAlloc在该容器存在大量内存分配时区别不显著。另外,由于内存池技术的作用,ScopeAlloc在Share同一个BlockPool后,性能略有改善。
分享到:
相关推荐
存放的中英翻译的模型数据,一个模型大概在220Mb左右,还有一些小的参数文件,共分为4个文件统一放在trainingzh_en_checkpoings\ckpt目录下
存放的中英翻译的模型数据,一个模型大概在220Mb左右,还有一些小的参数文件,共分为4个文件统一放在trainingzh_en_checkpoings\ckpt目录下
cccccccccc
{ "channels" : [ { "name" : "atmos#general" , "alias" : "peeps" } , { "name" : "atmos#hubot-test" } ] , "tokens" : [ "xoxp-aaaaaaaaa-bbbbbbbbb-cccccccccc-dddddd" , "xoxp-eeeeeeeee-fffffffff-...
aaaaaaaaaaaaaa cccccccccc dddddddddddd fffffffffffff </textarea> <input value=”1″ name=”line”> <input type=button onclick=”goL(parseInt(line.value));” value=”go”>...
CCCCCCCCCC llllllllll 3333333333 -- CCCCCCCCCCCCCCCCCC llllllllll 333333333333333333 -- CCCCCCC CCCCCCCCCC llllllllll 3333333333 333333 -- CCCCC CCC llllllllll 333 ## 33333 -- CCCCCC llllllllll # ...
C语言\Turbo C 2.0 汉化版 c语言编程\
android study!!!!good
专业技能参考.java