mik*_*lkh 6 c primes gcc memory-management
对于来自http://bellard.org/mersenne.html的程序,GCC可以生成~130MB的可执行文件.为什么?
axi*_*iom 12
尝试改变t[1<<25]={2},以t[1<<25]和*可执行文件的大小**将下降到7.3ķ.(不用说,你不会得到正确的结果)
如果它只是t[1<<25],它根本不会占用任何空间.
这里的问题是数组正在初始化(第一个元素= 2,接下来的2 ^ 25-1个元素全部为0),全局数组只是因为它被初始化而被放置在数据段中.
[axiom@axiom ~]$ diff without_mem.s with_mem.s
15c15,21
< .comm t,134217728,32
---
> .globl t
> .align 32
> .type t, @object
> .size t, 134217728
> t: ***<- HERE!***
> .long 2
> .zero 134217724
Run Code Online (Sandbox Code Playgroud)
我们可以注意到,在原始版本中,汇编器被指示在数据段中生成2 ^ 27(134217728)个字节.所以它成为目标文件本身的一部分.(您可以通过使用-S开关 进行编译来生成程序集gcc -S -fverbose-asm t1.c)
1<< n= 2^n (1 left shifted n times).
=> 1<<25=2^25.
now 1 Integer= 4 bytes =2^2 bytes
=> 2^25 Integers=2^27 bytes=2^7 * 1 M bytes= 128 MBs
注2:正如评论中所指出的,还可以注意到,即使可执行文件是7.3K,进程的总大小(执行中的程序)也将是129Mb.(程序开始执行后将分配内存).您可以使用该top命令查看程序的内存使用情况.
注3:值得强调的是,这只是因为t是全局的.函数本地数据的分配仍然在堆栈上的运行时发生.因此,如果t是本地的,目标文件将只采用7.3K.
注4:初始化的static局部变量,如初始化的全局变量,也保留在data段中.一个static全球是一样的,区别是你限制变量的作用域只对当前文件的全局.