我正在尝试生成一个大型单片应用程序的特殊版本。我试图解决的问题是跟踪难以重现的巨大内存分配(30-80千兆字节,根据操作系统报告来判断)。
我相信问题是std :: vector调整为负32位整数值。唯一表现出这种行为的平台是Solaris(也许它是唯一能够成功分配这些连续内存块的平台)。
我可以全局用我的类替换std :: vector,将所有调用委托给真实向量,并观察可疑分配(size > 0x7FFFFFFFu)
吗?也许有选择地替换采用size_t
和resize()
方法的构造函数?甚至可能劫持全球运营商新手?
答案 0 :(得分:5)
为什么不这样做?
void *operator new(size_t size)
{
// if (size > MAX_SIZE) ...
return malloc(size);
}
void *operator new [](size_t size)
{
// if (size > MAX_SIZE) ...
return malloc(size);
}
在if
中设置断点会立即发现问题。
答案 1 :(得分:2)
您可以在构建时为矢量提供自定义分配器。
您可以直接委托给std::allocator
,并防火墙请求的内存大小。
答案 2 :(得分:0)
查看问题平台上std::vector
类的实现。每个实现都以不同的方式处理内存管理(例如,当您在向量的当前分配大小之外添加对象时,当前分配的空间会增加一倍)。如果您的对象足够大和/或您有大量条目被添加到向量中,则可以尝试分配超出计算机上可用(连续)的内存。如果是这种情况,您将需要查看该向量的自定义分配器。
如果你在向量中存储了那么多大项,你可能想要查看另一个集合(例如std::list
)或尝试存储指针而不是实际对象。
答案 3 :(得分:0)
您可以提供自己的allocator
类型到std::vector
来跟踪分配。
但我怀疑这是原因。首先,看一下大小(30-80GB),我得出结论,它是一个64位代码。 32位负整数值如何使其成为矢量大小,即64位,它本来会被提升为64位以保留值?其次,如果此问题仅发生在Solaris上,那么它可以指示不同的问题。据我所知,Solaris是唯一一个在分配时提交内存的操作系统,其他操作系统只标记分配的地址空间,直到实际使用这些内存页。所以我会搜索未使用的分配。