在学习C的同时做了一些实验,我遇到了一些奇怪的事情.这是我的计划:
int main(void) {sleep(5);}
Run Code Online (Sandbox Code Playgroud)
编译时,可执行文件的文件大小为8496字节(与26字节源相比!)这是可以理解的,因为调用了sleep并且调用它的指令写在可执行文件中.另一个要点是,没有睡眠,可执行文件变为4312字节.
int main(void) {}
Run Code Online (Sandbox Code Playgroud)
我的主要问题是第一个程序运行时会发生什么.我正在使用clang编译和Mac OS X来运行它.结果(根据Activity Monitor)是程序使用504KB的"真实内存".当程序只有4KB时为什么这么大?我假设可执行文件已加载到内存中但除了睡眠调用之外我没有做任何事情.为什么我的程序需要500KB才能睡5秒钟?
顺便说一句,我使用sleep的原因是首先能够使用Activity Monitor捕获正在使用的内存量.
我只是出于好奇而欢呼,欢呼!
编译C程序时,它会链接到可执行文件中.即使您的程序非常小,它也会链接到C运行时,其中包含一些额外的代码.可能存在一些错误处理,并且此错误处理可能会写入控制台,此代码可能包括sprintf为应用程序添加一些占用空间.您可以请求链接器生成可执行文件中的代码映射,以查看实际包含的内容.
此外,可执行文件包含的不仅仅是机器代码.将存在用于数据和动态链接的各种表格,这将增加可执行文件的大小,并且还可能存在一些浪费的空间,因为各个部分存储在块中.
C运行时将在main调用之前初始化,这将导致一些代码被加载(例如,通过动态链接到各种操作系统功能)以及为堆分配的内存,每个线程的堆栈以及可能还有一些静态数据.并非所有这些数据都可能显示为"真实内存" - OS X上的默认堆栈大小似乎为8 MB,而您的应用程序仍然使用的数据远远少于此.