我怎样才能知道C ++类的一个实例消耗了多少内存?

时间:2010-03-19 14:46:32

标签: c++ object memory memory-management

我正在开发一个基于boost-graph-library的Graph-class Graph-object包含一个boost图,也就是说一个adjacency_list和一个map。 在监视程序的总内存使用量时,它会消耗很多(使用pmap检查) 现在,我想知道,这个Graph类的填充对象有多少内存被消耗?填充时我的意思是当adjacency_list充满顶点和边缘时 我发现,使用sizeof()并没有给我带来太大的影响。使用valgrind也是不是的替代方法,因为以前完成了相当多的内存分配,这使得valgrind的使用不切实际。我也对程序的其他部分内存成本不感兴趣,我想专注于一个对象。

谢谢。

3 个答案:

答案 0 :(得分:3)

如果您能够控制对象的创建和填充,以便在此期间不执行任何其他分配,那么执行此操作的一种方法是使用您的newdelete运算符覆盖自己的版本,只计算总分配大小并将其存储在全局变量中。抓取开头和结尾的总大小,差异应该是所用大小的合理近似值(不计算堆开销)。

答案 1 :(得分:1)

我从未使用adjacency_list所以这只是一个想法虽然适用于STL容器。

所以using adjacency_listBGL uses containers from the STL such as std::vector, std::list, and std::set to represent the set of vertices and the adjacency structure。好的,那么你只需要给你的相邻列表std :: vector,std :: list和std :: set有自己的分配器类型。 Adding your own allocator to STL containers is an easy task。完成所有这些后,您只需从分配器中获取填充adjacency_list时已分配的内存大小。

所以我的想法是用STL容器构建相邻的列表(在快速查看BGL文档后看起来可能),它们有自己的分配器类型。

更新1 实际上你还没有告诉为什么你需要知道你的图表消耗多少字节。如果你只需要获得这个数字,你可能需要在编写程序时填写图表。然后运行例如UNIX95= ps -u $USER -o vsz,args并找出差异。大致你会得到你的图表大小。

如果您需要在应用程序中定期获取此值,并且如果您无法使用分配器实现整个解决方案,则需要从几个小步骤开始。

  1. 了解分配器: C++ Standard Allocator, An Introduction and Implementation Allocators(STL)
  2. 尝试使用您自己的分配器作为练习实现std :: vector
  3. 尝试将计数字节添加到分配器
  4. 尝试使用allocator构建Boost图 Customizing the Adjacency List Storage
  5. 做一些事情来计算容器的std :: string成员中的字节数。默认情况下,他们不会使用其容器的分配器。因此,要么使用固定大小的字符串,要么以某种方式管理容器的分配器在此字符串成员中。再次,看看Adding your own allocator to STL containers
  6. 顺便说一句,如果你不想重新发明C ++分配器,你可以使用类似的东西:

    template <typename T> class your_allocator {    
    public:
    // here you need to put everything that is required by C++ standard
    // and calls finally send to std_allocator_    
    private:
        std::allocator<T> std_allocator_;    
    };
    

答案 2 :(得分:0)

到目前为止,我设法将所有内容缩小,我可以考虑用valgrind进行分析 然后我使用“--tool = massif”来检查堆内存消耗。我使用以下代码创建了我的Graph-class

的实例
    typedef Graph<VertexProperties, EdgeProperties> MyGraph;
    MyGraph* G;
    G = new MyGraph(*vertex_props);

构造函数以这样的方式构建,它接收一个与边相等的VertexProperties对列表,然后通过adjacency_list存储所有内容。
然后,地块剖面返回了以下结果。为简单起见,我将它们发布在一个pastebin中:http://dpaste.com/hold/174033/
您可以在那里看到整体执行的图表,并且在快照83处达到达到235.4MiB的峰值 我的问题是,这是我的程序消耗的堆上的总内存总量吗?大概怎么样? pmap为我的程序返回1GB的内存使用量?这些价值观如何结合在一起? 最重要的是,在查看快照83的详细信息时,可以说:

  1. 32.76%(80,842,846B)for std :: string :: _ Rep :: _ S_create(....)
  2. 15.94%(39,341,760B)std :: _ Rb_tree&gt;
  3. 主要的11.91%(29,389,824B)(new_allocator.h:92)
  4. 我是否正确,1。告诉我约。 std :: string消耗了80MB,而且告诉我,我的Graph占用了大约。 40MB?
    什么3.然后告诉我?

    谢谢。