0

我想分别测量堆栈、堆和静态内存,因为我对每一个都有一些限制。

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

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

  • 最后一个带有 --stacks=yes 的快照提供了 total(B)= 2,256,有用堆(B)=1,040,extra-heap(B)=0,stacks(B)=1,208(即使它是相同的命令和相同的二进制测试...不知道为什么...)

所以最后我需要一个工具来测量 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);
        …
    }
    
4

2 回答 2

2

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

  • 要测量堆内存,请使用 valgrind -> massif

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

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

它给了我想要的所有数据

于 2018-02-23T15:19:13.157 回答
2

我想分别测量堆栈、堆和静态内存,因为我对每一个都有一些限制。

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

如果您考虑进程的实际虚拟地址空间,您的定义是幼稚的。

顺便说一句,proc(5)使您能够查询该空间,例如从程序内部使用/proc/self/mapslike here(或/proc/1234/maps查询 pid 1234 的进程,可能从终端)。您也可以使用/proc/self/statusand /proc/self/statm(顺便说一句cat /proc/self/mapscat /proc/$$/maps在终端中尝试)。在 Linux 上,您还可以使用mallinfo(3)malloc_stats(3)来获取有关内存分配统计信息的信息。

静态数据可能位于程序的数据段(或BSS段)中。但是线程本地空间呢?这些数据段还包含各种库的内部数据,尤其是 C 标准库libc.so(这算不算?)。当然,堆栈段通常比实际使用的堆栈(从“底部”到当前%esp寄存器)更大(因为页面对齐)。多线程进程有多个堆栈(和堆栈段),每个线程一个。

堆栈数据当然在调用堆栈中,其中包含许多其他内容(返回地址、间隙、溢出的寄存器),而不仅仅是自动变量(其中一些仅位于寄存器中或由编译器优化,不占用任何堆栈槽)。他们算吗?此外,来自crt0的启动代码(调用 your main)可能会使用一点堆栈空间(这算不算?)...

堆分配的数据(它可以从各种库分配,甚至从动态链接器分配)不仅包含您的程序从malloc(和朋友)获得的内容,还包含必要的开销。这算不算?那么内存映射文件呢?他们应该如何计算?

我建议查询实际的虚拟地址空间(例如通过读取/proc/self/maps或使用pmap(1) ...),但您得到的结果与您所要求的不同。

于 2018-02-23T12:08:39.440 回答