为什么动态链接导入(在Windows中)总是在应用程序启动时加载?

阿鲁斯·阿加兰普尔

动态链接到库的一个好处是,当调用该库中的函数时,将其加载到程序的虚拟地址空间中,然后调用该函数。静态链接会加载整个可执行文件,从而占用空间。

在Windows上,当加载程序时,所有函数导入都将在调用程序入口点之前解决。例如:kernel32.dll!VirtualFree加载所有需要的库,然后调用程序的入口点。

这与静态链接的可执行文件有何不同?如果同时加载所有引用的库,是否会占用相同的空间?有什么好处?请帮助我理解。

迈克·金汉

就事实而言,它是不是有必要对所有在其上的Windows应用程序依赖它启动时要加载的DLL。从Visual C ++ 6.0(1998)开始,MS链接器支持该/DELAYLOAD选项选项推迟DLL的加载,直到且除非调用其导出之一。

默认行为是在启动时加载DLL。我假设您想知道默认行为如何与在内存占用空间以及更一般的意义上链接静态库之间进行权衡。

假定具有相同实现的相同API作为静态库libfoo.lib和动态库构建libfoo.dll

只要libfoo.dll在给定的时间仅需要一个程序,那么与该程序静态链接时在同一时间所消耗的内存至少相同libfoo.lib

实际上,加载DLL的程序版本比与静态库链接的版本消耗的内存更多这是因为第一次加载DLL时,整个DLL都加载到了内存中。但实际上,事实并非并非如此,当程序与静态库链接时,整个静态库必须合并到可执行文件中。一个静态库是简单对象文件的归档,从该连接器在默认情况下只提取定义由程序引用符号,链接那些他们到程序中,忽略其它。因此,如果程序不需要将所有目标文件存档在libfoo.lib,则静态链接libfoo.lib所需的内存将小于动态链接所需的内存libfoo.dll

但是,一旦同时需要多个运行程序,则内存成本开始开始向DLL倾斜libfoo.dll这是因为DLL由不同的代码和数据部分组成,加载器可以分别加载它们。每个需要的并发程序都需要libfoo.dll拥有自己的DLL数据副本,但是它们都可以执行其代码的同一副本libfoo.dll为第一个需要它的程序加载了代码和数据部分之后,加载器只需要为需要的并发程序加载其数据的新副本

因此,当我们考虑整个运行系统的内存占用量时,其中许多并发进程可能需要单个库提供的服务,因此在DLL中而不是静态库中实现此类服务是一种经济的策略。

DLL的主要目的是以这样一种方式提供服务:无论有多少并发程序正在执行它,都仅需加载实现代码的一个副本。

但是它们还有另一个重要的好处,即使对于只可能被一个应用程序使用的库也是如此。制作新版本的foo库(提供错误修复或增强功能)后,可以将此版本部署到已与静态库链接的程序中的唯一方法libfoo.lib是重新链接,重新分发并重新安装所有这些程序。但是只要新版本的libfoo保留了现有的API,与链接的程序就根本不需要做任何事情libfoo.dll只需分发和安装的新版本libfoo.dll,这些程序将在下次运行时加载它。应用程序架构师可以选择实现特定应用程序的模块 精确地在DLL中提供功能,以便可以部署此功能的更新,而不必要求最终用户重新安装该应用程序。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Windows启动时加载桌面应用程序

启动时.NET中的控制台应用程序和Windows应用程序有什么区别

在启动时加载外部链接的Phonegap应用程序-Android

在Windows启动时启动WPF应用程序

在应用程序启动时加载hazelcast imap

在应用程序启动时预加载ViewController

应用程序启动时如何加载片段

WPF 在应用程序启动时加载 texbox 内容

Alarmmanager.set() 总是在应用程序启动而不是预期时间时触发

Windows启动时加载应用程序。然后自动缩放和定位呢?

我的应用程序在启动时崩溃,我不确定为什么

为什么我的 React Native 应用程序在启动时崩溃而没有任何错误?

启动应用程序后立即加载动态链接的DLL

将字典保存在应用程序设置中并在启动时加载它

启动时启动应用程序

启动时启动应用程序

Windows 10启动时的“我的”应用程序

为什么`xmodmap` 并不总是在登录时加载`.Xmodmap`?

总是在从应用程序中的任何路由刷新时重定向到主页

检测用户单击或Windows启动时在C#中运行的应用程序

为什么导入后运行Docker镜像时无法启动应用程序

为什么在使用application.conf中的MySQL安装程序启动时,Play 2.3应用程序会在启动时给我“找不到驱动程序:[com.mysql.jdbc.Driver]”的信息?

Pubnub 总是在 Django 应用程序中超时

NSMutableArray总是在加载时启动

使用 Firebase 数据库的 Android 应用程序在启动时总是崩溃?

为什么android应用程序动态创建的“动态链接”不能直接打开应用程序?

chrome总是在关联的应用程序中打开这些类型的链接硒中缺少复选框

应用程序是否继续加载不应在应用程序启动时启动的页面?

我的应用程序启动时如何将数据加载到我的表中?