测量静态,堆和堆栈内存? (c ++,Linux - Centos 7)

时间:2018-02-21 16:17:37

标签: c++ valgrind heap-memory stack-memory static-memory-allocation

我想分别测量堆栈,堆和静态内存,因为每个都有一些约束。

使用valgrind-> massif工具测量堆内存。 Massif也应该可以测量堆和堆栈内存,但它显示奇怪的结果:

  • 没有--stacks = yes的上一个快照提供总(B)= 0,有用堆(B)= 0,额外堆(B)= 0(所以一切都很好)

    < / LI>
  • 使用--stacks = yes的最后一个快照提供总计(B)= 2,256,有用堆(B)= 1,040,额外堆(B)= 0,堆栈(B)= 1,208(显示内存)即使它是相同的命令和相同的二进制测试... dunno为什么......)

所以最后我需要一个工具来测量c ++二进制文件使用的堆栈和静态内存,欢迎使用一些帮助:)

感谢您的帮助!

-----------编辑--------------

继Basile Starynkevitch评论之后,为了解释我对静态,堆栈和堆内存的意义,我从Dmalloc库文档中得到了它:

  • 静态数据是将存储空间编译到程序中的信息。

    /* global variables are allocated as static data */
    int numbers[10];
    
    main()
    {
            …
    }
    
  • 堆栈数据是在运行时分配的数据,用于保存函数内部使用的信息。该数据由系统在称为堆栈空间的空间中管理。

    void foo()
    {
            /* if they are, the parameters of the function are stored in the stack */
            /* this local variable is stored on the stack */
            float total;
            …
    }
    
    main()
    {
        foo();
    }
    
  • 堆数据也在运行时分配,为程序员提供动态内存功能。

    main()
    {
        /* the address is stored on the stack */
        char * string;
        …
    
        /*
         * Allocate a string of 10 bytes on the heap.  Store the
         * address in string which is on the stack.
         */
        string = (char *)malloc(10);
        …
    
        /* de-allocate the heap memory now that we're done with it */
        (void)free(string);
        …
    }
    

2 个答案:

答案 0 :(得分:2)

  

我想分别测量堆栈,堆和静态内存,因为每个都有一些约束。

我无法想象你为什么每个人都有单独的约束。他们都坐在virtual memory!顺便说一句,您可以使用setrlimit(2)来设置限制(可能来自调用shell进程,例如使用bash ulimit内置)。

如果您考虑过程的实际virtual address space,那么您的定义是天真的。

BTW,proc(5)可让您查询该空间,例如在程序中使用/proc/self/maps /proc/1234/maps,或/proc/self/status查询pid 1234的过程,可能来自终端。您还可以在终端中使用/proc/self/statmcat /proc/self/maps(BTW尝试cat /proc/$$/mapslibc.so)。在Linux上,您还可以使用heremallinfo(3)来获取有关内存分配统计信息的信息。

静态数据可能位于程序的malloc_stats(3)(或data segment段)中。但是线程局部空间怎么样?并且这些数据段还包含各种库内部的数据,特别是C标准库%esp(这样算吗?)。当然,堆栈段通常比实际使用的堆栈(从“底部”到当前main寄存器)更大(因为页面对齐)。多个BSS进程有几个堆栈(和堆栈段),每个线程一个。

堆栈数据当然是在调用堆栈中,它包含许多其他内容(返回地址,间隙,溢出寄存器),而不仅仅是threaded(其中一些只位于寄存器中或由编译器优化) ,不消耗任何堆栈槽)。他们算了吗?此外,来自automatic variables的启动代码(调用您的malloc)可能会占用一小部分堆栈空间(它会计算吗?)......

堆分配的数据(可以从各种库中分配,甚至可以从动态链接器分配)不仅包含程序从/proc/self/maps(和朋友)获得的内容,还包含必要的开销。这算了吗?那么crt0呢?他们应该怎么算?

我建议查询实际的虚拟地址空间(例如,通过阅读private int sumMagicRow(int size,int col) { int sum = 0; for (int i=0;i<(size);i++) { sum += square[col][i]; } col++; return sum; } 或使用memory-mapped files ...)但是你会得到与你提出的不同的东西。

答案 1 :(得分:1)

顺便说一句,我在你回答之前就找到了它:

  • 要测量堆内存,请使用valgrind - &gt;地块

  • 要测量静态内存,请使用二进制文件上的bash函数size

  • 要测量堆栈,可以使用stackusage

它给了我所有我想要的统计数据