C程序的内存分析

8
需要对我的C应用进行内存分析,其中包括占用空间大小和RAM大小。
例如,如果我的应用程序如下所示:
#include <stdio.h>

int global = 10; /* initialized global variable */

int test_code(void)
{
    static int i = 100; /* Initialized static variable*/
    return 0;
}

输出:

[putta@linux]$ gcc memory-layout.c -c memory-layout 

[putta@linux]$ ls -ltrh  memory-layout.o
760 Nov  9 18:26 memory-layout

[putta@linux]$ size memory-layout.o
   text    data     bss     dec     hex filename
     67       8       0      75      4b memory-layout.o

现在应该考虑哪种内存来分析占用情况,当程序被加载时是指RAM。

下面的分析是否正确? 占用内存 = 760 (位于闪存或硬盘上) RAM = 67+8+0 = 75 字节

需要专家建议。


如下所述,这不是一个程序。无论运行的程序可以分配内存(即malloc),都将计入已使用的内存(当然在二进制文件中不可见)。 - hexasoft
你需要定义“内存占用”。据我所知,它包括程序代码、静态存储变量、堆栈使用和堆使用的总RAM使用量。 - Lundin
是的,由于堆取决于实时数据,我想在没有堆和栈的情况下进行计算...所以在我的情况下,我需要像下面这样计算RAM =程序代码、静态和全局变量,FLASH =存储程序所需的总内存(常驻内存)。 - putta ks
我编辑了我的回答以满足你的问题。 - terence hill
2个回答

6

查找对象的内存大小

如果您想知道程序在磁盘上的大小以及RAM中文本和数据的大小,则在Linux / Unix上可以使用size命令:

$> size /bin/cat
text       data     bss     dec     hex filename
43422      1720    2472   47614    b9fe /bin/cat

size命令的输出是目标文件不同部分的内存大小:

  • text:(代码段)可执行指令
  • data:(数据段)初始化的全局变量
  • bss:(块开始于符号)静态分配的变量

最后两列dechex分别是三个列的总和(总大小)的十进制和十六进制。

您正在请求的大小是:ls的输出(给出磁盘上的大小)加上size命令的dec部分的输出(给出RAM上的大小)。

另请参阅以下内容:http://www.cyberciti.biz/faq/linux-find-size-of-text-data-segment-bss-uninitialized-data/如何知道我的二进制可执行文件的内存占用情况

查找内存占用情况

当涉及到软件应用程序时,占用情况表示运行进程消耗的内存大小(运行时内存需求)。

因此,在进程运行时应检查内存占用情况。我认为(其他文章也证实了这一点),唯一真正的选择是使用像valgrind这样的工具。

使用valgrind对应用程序进行分析

您可以使用Massif工具对内存进行分析。 Massif是一个分析器,但也可以测量的大小。

valgrind --tool=massif --stacks=yes

这将为您提供内存使用情况。然后,信息存储在文件massif.out.?????中,您可以使用以下命令读取:

ms_print massif.out.?????

文件中的第一个输出是在运行时间内内存使用情况的漂亮图表。
--------------------------------------------------------------------------------
Command:            ./myprog -f d5.ini
Massif arguments:   --stacks=yes
ms_print arguments: massif.out.24377
--------------------------------------------------------------------------------


    MB
5.292^                                                    ##                  
     |    @                 :           :  @@   :      :  # ::::   :  :       
     |    @:::: ::    :   :@:@@::::::::::::@ :::::::::::::# ::::@::::@::::::::
     |    @:: ::: :::::::::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |    @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |    @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |    @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |    @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |    @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |    @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |   @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     |   @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | ::@@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
     | : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
   0 +----------------------------------------------------------------------->Gi
     0                                                                   1.030

这些细节存储在文件中,分别位于不同的表格内。 要完全理解输出,请参阅Valgrind手册page,该手册似乎非常清晰。
跟踪子进程的选项是:--trace-children=yes 有趣的是,似乎没有"进程的实际内存使用情况": https://unix.stackexchange.com/questions/164653/actual-memory-usage-of-a-process

我只需要计算存储程序所需的内存和加载程序所需的RAM。在我的应用程序中,堆和栈取决于用户实时数据,因此目前我只想计算这些东西。 - putta ks
实际磁盘字节大小(与ls一样)+ dec(size的输出)...这正确吗? ls获取完整的目标文件大小(包括所有部分的大小),因此应该是“仅在磁盘上的实际字节大小”,对吗? - putta ks
是的,我的意思是“磁盘上的实际大小= ls”+“RAM上的大小= dec”。我编辑了文本,希望现在更清晰了。 - terence hill
为了更好地可视化valgrind的输出,有一个很好的GUI应用程序massif visualizer。它可以在基于Debian的系统上通过apt install massif-visualizer进行安装。然后运行massif-visualizer massif.out.?????。还可以参见这个 - EsmaeelE

2

这个程序未定义:缺少main函数。

在这种情况下,编译器保留不编译任何内容的权利,因此导致零占用空间和内存大小。


实际上,我正在将我的功能制作为动态库。目前我不需要堆栈和堆内存。我只需要计算在闪存中存储程序所需的内存以及将我的库加载到RAM以供执行所需的内存。 - putta ks
那么,为什么你把你的代码称作“应用程序”呢? :-) - Bathsheba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接