swe*_*egi 11 c++ memory-management stl
我有一个大量使用的程序std::map
.在Windows下,Linux下使用的内存要多得多.有谁知道为什么会这样?
Linux的:
Last process took 42.31 s and used not more than 909 MB (RSS 900 MB) of memory
视窗:
Last process took 75.373 s and used not more than 1394 MB (RSS 1395 MB) of memory
我在命令行上使用gcc 4.4.3和VS 2010 C++编译器,具有发布设置.
编辑:很抱歉回答最近的问题......
代码如下所示:
enum Symbol {
...
}
class GraphEntry {
public:
...
virtual void setAttribute (Symbol name, Value * value) = 0;
const Value * attribute (Symbol name) const;
private:
std::map<Symbol, Attribute> m_attributes;
};
class Attribute {
public:
Attribute (Symbol name, Value * val);
...
Symbol name () const;
Value * valuePointer () const;
void setValuePointer (Value * p);
private:
Symbol m_name;
Value * m_value;
};
class Graph : public GraphEntry {
...
public:
Node * newNode (...);
Graph * newSubGraph (...);
Edge * newEdge (...);
...
setSomeAttribute (int x);
setSomeOtherAttribute (float f);
...
private:
std::vector<GraphEntry *> m_entries;
};
Run Code Online (Sandbox Code Playgroud)
整个过程描述了一个图形结构,它可以在其节点和边缘上保存一些属性.Value
它只是一个基类,派生类可以包含任意类型的值,如int
或std::string
.
编辑2:在Windows下,我使用以下标志: -DRELEASE -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DNOMINMAX /O2 /MD /Gy /EHsc
编辑3:从linux下的/ proc文件中读取内存使用情况(如memuse
).在Windows下,调用了一些WinAPI函数,但我不是这方面的专家,所以这就是我所能说的.
编辑4:使用/GS-
和-D_SECURE_SCL
结果Last process took 170.281 s and used not more than 1391 MB (RSS 1393 MB) of memory
你会发现Windows上的内存使用量大约是1到2倍.除了堆算法,Windows malloc()
,以及随后在堆上分配的任何数据结构new
(例如std::map
具有默认分配器类型的节点)都与16个字节对齐.在Linux上,glibc默认为8字节对齐.假设由于碎片,优化收获未使用的页面等而导致差异平滑,您可以预期差异将变得不那么明显
快速检查代码表明映射键和值类型应分别为4和8字节(Symbol
和Attribute
).这些将在Linux上最多8个字节,在Windows上最多16个字节.您应该有相同数量的映射节点,至少在MSVC实现中,这些映射看起来至少消耗22个字节,由于其成员对齐规则,MSVC将扩展为32,这也是它的malloc粒度.GCC将其扩展到24,意味着MSVC到GCC/Linux的每个节点大约有48个字节.Windows上的内存使用量大约增加50%.
这是MSVC中使用的节点结构,如果您感兴趣,我可以查看GCC等效项:
struct _Node
{ // tree node
_Nodeptr _Left; // left subtree, or smallest element if head
_Nodeptr _Parent; // parent, or root of tree if head
_Nodeptr _Right; // right subtree, or largest element if head
value_type _Myval; // the stored value, unused if head
char _Color; // _Red or _Black, _Black if head
char _Isnil; // true only if head (also nil) node
Run Code Online (Sandbox Code Playgroud)
我会为那些不熟悉内存使用情况的人添加内容,有几个因素在起作用:
malloc()
正在使用对齐规则(除非您破坏通常的堆或使用除默认值之外的其他分配器).每个编译器都附带自己的STL实现,因此您要进行比较:
在这里绘制有意义的比较是相当困难的,因为您不知道哪个分配例程或STL实现(或可能两者)实际上负责.
我确实假设你没有将32位程序与64位程序进行比较,因为这样做的意义就更小了.