为啥某些 VB6 DLL 被加载为映射文件?

Posted

技术标签:

【中文标题】为啥某些 VB6 DLL 被加载为映射文件?【英文标题】:Why are some VB6 DLLs loaded as mapped files?为什么某些 VB6 DLL 被加载为映射文件? 【发布时间】:2010-04-23 09:08:23 【问题描述】:

我的一位同事在尝试计算我们的 VB6 / C# 2.0 应用程序的内存使用情况时注意到少数 VB6 DLL 在 SysInternals Process Explorer 应用程序中有两个条目。

所有 DLL 都有一个 Mapping = Image 条目和一个指定的基地址。但是,少数也有Mapping = Data 的条目,基地址为零,内存使用量要小得多。我似乎记得一些关于使用映射内存文件在进程之间共享内存的事情,但我们绝对没有做像这样有趣的事情。 EXE之间的所有通信都是通过COM完成的,据我所知,没有人写过共享内存组件。

关于为什么某些 DLL 被加载为映射文件的任何建议?

【问题讨论】:

【参考方案1】:

很久以前,但我确实记得 Visual Basic 的本机执行模型是解释 P 代码。在 VB4 时代的某个地方,它开始支持编译为本地机器代码。主要是为了与 Borland 的 Delphi、IIRC 保持竞争力。

P 代码将作为数据加载,并且比机器代码更紧凑。而且慢得多。机器代码将像 Windows 中的任何 DLL 一样被加载,内存映射文件将代码页错误地加载到内存中。

【讨论】:

好建议。您可以使用项目设置在 P 代码和本机代码之间切换。也许大多数 DLL 都设置为原生编译,但其他少数 DLL 设置为 P-Code。 好主意!但是,我们的项目都没有设置为 P-Code。另外,我特意为 P-Code 设置了一个 DLL,而 P-Code 肯定只包含在 Image 中 - 没有进行文件映射。 这里的每个人都在猜测这有点好笑;)谁可以回答这个问题,然后用 Windows 编程 不值得? 嗯,他们读了它并且知道它根本没有说任何关于 VB6 或 P 代码解释器的内容。 P 代码有时会更快。这几乎完全是由于加载时间和缓存容量方面的“越小越好”因素。它在高并发服务器场景中可能更为重要。【参考方案2】:

只是猜测,但您的任何 DLL 是否在 BAS 模块中声明了 PublicGlobal 变量?如果是这样,它们在您的 DLL 中的所有对象之间共享并且它们可能存储在数据区域中?

一个更疯狂的猜测。您使用的是 XP 吗?当 EXE 加载这些 DLL 时,它们是否得到了rebased? (您可以ask Process Explorer 以另一种颜色突出显示重新设置的 DLL)。您可以通过changing the base address 防止变基。即使它不解释小内存区域,它也会使 DLL 加载更快。

【讨论】:

Mark - 好吧,我们确实有声明了全局变量的 DLL,但这样做的那些 DLL 只与那些有文件映射的 DLL 重叠,而不是重合。至于变基 - 我自己也想知道,但它似乎与这种情况无关。 @Mark B 哦,好吧,我想我会尝试一些猜测。【参考方案3】:

内存映射的 DLL 是否可以是其中嵌入了资源的 DLL?我不确定Windows(或VB6,就此而言)通常如何处理DLL中的资源,但我想知道在VB6中使用.res文件显式编译的DLL是否是出现两次的DLL。

也许这样做是为了当两个 EXE 加载同一个 DLL 时,它们可以共享 DLL 资源的一个副本。不过我完全猜到了。

【讨论】:

好主意,迈克,我最初想知道是不是这样。不幸的是,我们只有一个组件使用资源,并且没有表现出这种行为。【参考方案4】:

添加另一个疯狂的猜测:

这些 PE 文件中是否有可能使用 /SWAPRUN 设置链接?

/SWAPRUN 选项告诉 操作系统要先复制 链接器输出到交换文件,然后 从那里运行图像。这是一个 Windows NT 4.0(及更高版本)功能。

如果指定了 NET,则操作 系统将首先复制二进制文件 从网络到交换文件的图像 并从那里加载它。这个选项是 对运行应用程序很有用 网络。指定 CD 时, 操作系统将复制图像 可移动磁盘上的页面文件和 然后加载它。

【讨论】:

以上是关于为啥某些 VB6 DLL 被加载为映射文件?的主要内容,如果未能解决你的问题,请参考以下文章

某些加载的 FBX 文件的纹理映射失败

在VB6中编译DLL时“加载DLL时出错”

为啥我的 DLL 只能通过手动映射注入?

DLL文件劫持应该怎么办 急啊

从 64 位应用程序加载/与 vb6 COM dll 交互

dll被加载后线程的问题