它在执行之前是否将整个二进制文件复制到内存中?我对这个问题很感兴趣,并希望将其改为其他方式.我的意思是,如果二进制文件是100M大(似乎不可能),我可以运行它,而我将它复制到内存中.这有可能吗?
或者你能告诉我如何看待它的运行方式吗?我需要哪些工具?
BRP*_*ock 33
应用程序级程序员的理论模型看起来就是这样.事实上,正常的启动过程(至少在Linux 1.x中,我认为2.x和3.x是优化但相似)是:
ld.so
程序(例如/lib/ld-linux.so.2
)为共享库设置内存映射jmp
程序的启动例程(对于C程序,就像crtprec80
调用它一样main
).由于它只设置了映射,并没有实际加载任何页面(*),因此会导致来自CPU内存管理单元的页面错误,这是内核的中断(异常,信号).malloc
/时new
,内核会创建RAM的读写页面(没有光盘后备文件)并将它们添加到你的虚拟地址空间.malloc
),它们会被写入(页面文件=交换文件=交换分区=盘上虚拟内存).访问这些"释放"页面会导致另一个页面错误,并且它们会被重新加载.但是,一般情况下,直到你的进程比可用的RAM大 - 并且数据几乎总是比可执行文件大得多 - 你可以安全地假装你在世界上独自一人而且这种请求分页的东西都没有发生.
所以:实际上,内核在加载程序时已经在运行你的程序(如果你从未加入那些代码/引用那些数据,可能永远都不会加载某些页面).
如果您的创业公司特别迟钝,您可以查看prelink
系统以优化共享库负载.这减少了ld.so
启动时(在exec
程序和main
被调用之间以及首次调用库例程时)必须执行的工作量.
有时,静态链接可以提高程序的性能,但占用RAM的主要费用 - 因为您的库不是共享的,所以libc
除了libc
每个其他程序正在使用的共享之外,您还要复制"您的" .这通常仅适用于程序在机器上单独运行的嵌入式系统.
(*)实际上,内核有点聪明,并且通常会预加载一些页面以减少页面错误的数量,但理论是相同的,无论优化如何