我有一个带有一个 exe 和三个 Dll 的小型测试解决方案,该 exe 分别调用三个 Dll 一次。我已将Dll1.dll、Dll2.dll 和 Dll3.dll 的 Build- >Advanced->DLL Base Address设置分别设置为 0x41000000、0x42000000 和 0x43000000。我跑了
ngen install ConsoleApplication1.exe
这已经成功地将应用程序与三个 Dll 一起生成。我真的不想生成 exe,但到目前为止,这是产生任何结果的唯一方法。
在运行时,我使用 VMMap 监视虚拟地址空间,它显示 ngen 的 Dll 位于一致的虚拟内存范围内,但是它们仍在该范围内跳跃,每次我运行时加载的地址都略有不同他们。VMMap 显示在我尝试加载图像的地址上没有分配任何内容,因此这种跳跃行为不是由地址冲突引起的。
我一直在记录日志:
Dll1 Dll2 Dll3
0x40140000 0x411D0000 0x42810000
0x40580000 0x41EB0000 0x426B0000
0x40190000 0x41FB0000 0x42380000
0x40F30000 0x41FD0000 0x42050000
0x409B0000 0x41BF0000 0x42910000
0x408E0000 0x41860000 0x42050000
0x40B50000 0x41280000 0x42A80000
请注意,地址的前两位数字在所有运行中对于所有三个 Dll 保持一致。
我的实际问题是:这是成功的指标吗?我有点困惑,因为我认为 Dll 将恰好位于 0x41000000、0x42000000 和 0x43000000。结果表明他们在那个区域徘徊,但从未真正坐在我让他们坐的地方。我的理解是,您希望将 Dll 准确地加载到您要求它们加载的地址,这样它们就不必进行昂贵的变基操作(当您的 Dll 被 ngen'd 时,这非常昂贵)。但是,这不正是正在发生的事情吗?当然,我的 Dll 在某个区域徘徊,但它们并没有完全坐在我要求它们坐的位置,所以每次运行时肯定会执行昂贵的变基操作吗?这正是我想要避免的。
注意:我对支持/反对 rebase 和 ngen 的论点不感兴趣。我只想知道发生了什么以及如何让它工作。
干杯!