我们需要用这个标志链接我们的一个可执行文件,因为它使用了大量的内存。
但是为什么要对一个EXE文件进行特殊处理呢?为什么不在/LARGEADDRESSAWARE上实现标准化呢?
所以问题是:即使你不需要/LARGEADDRESSAWARE,使用它也有什么错吗?为什么不把它作为所有EXE文件的标准?
发布于 2014-03-30 23:05:27
盲目地将LargeAddressAware标志应用于您的32位可执行文件将部署一个定时炸弹!
通过设置此标志,您可以向操作系统证明:
是的,我的应用程序(以及在运行时加载的所有all )可以处理高达4 GB的内存地址。
因此,不要将进程的VAS限制为2 GB,而是解锁整个范围(4 GB)。
但你真的能保证吗?
您是否对您的进程可能使用的所有系统DLL、microsoft可再发行文件和第三方模块负责?
通常,内存分配以从低到高的顺序返回虚拟地址。因此,除非您的进程消耗大量内存(或者它具有非常零碎的虚拟地址空间),否则它永远不会使用超过2 GB边界的地址。这隐藏了与高地址相关的bug。
即使存在这样的bug,也很难识别。他们迟早会零星地出现。这只是个时间问题。
幸运的是,windows操作系统中内置了一个非常方便的系统级开关:
出于测试目的,请使用MEM_TOP_DOWN注册表设置。
这会强制所有内存分配自上而下,而不是正常的自下而上。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"AllocationPreference"=dword:00100000(这是十六进制0x100000。当然,需要重新启动windows )
启用此开关后,您将“更快”地发现问题,而不是“稍后”。理想情况下,你会“从一开始”就看到它们。
附注:对于第一次分析,我强烈推荐使用工具VMmap (SysInternals)。
结论:
将LAA标志应用于32位可执行文件时,必须在设置了AllocationPreference x64 开关的TopDown OS上对其进行全面测试。
对于您自己的代码中的问题,您也许能够修复它们。
举个很明显的例子:内存指针使用无符号整数而不是有符号整数。
当遇到第三方模块的问题时,您需要请求作者修复他的错误。除非这样做,否则最好从可执行文件中删除LargeAddressAware标志。
关于测试的注释:
对于由本身未启用MemTopDown的“测试运行器”执行的单元测试,LAA注册表开关无法获得所需的结果。
请参阅:Unit Testing for x86 LargeAddressAware compatibility
PS:
从32位代码到64位代码的迁移也是非常“相关”和非常有趣的。
有关示例,请参阅:
发布于 2010-02-18 21:05:56
因为许多遗留代码都期望“负”指针是无效的。32位进程的前两Gb中的任何内容都设置了msb。
因此,对于微软来说,采取安全措施要容易得多,并且需要(a)需要完整的4 4Gb和(b)已经在大内存情况下开发和测试的应用程序,以简单地设置标志。
正如你已经注意到的,这并不难。
Raymond Chen -在他的博客The Old New Thing中-涵盖了为所有(32位)应用程序打开它的问题。
发布于 2011-01-19 20:05:02
不,在这个上下文(C/C++)中的“遗留代码”并不是唯一使用MSB指针的丑陋把戏的代码。
它还包括所有使用“int”来存储两个指针之间的差异或内存区长度的代码,而不是使用正确的类型“size_t”:“int”被签名有31位,并且不能处理超过2 Gb的值。
修复大部分代码的一种方法是检查并纠正所有那些无害的“混合签名和未签名”警告。它应该做了很好的工作,至少如果你还没有定义函数,其中int类型的参数实际上是一个内存长度。
然而,“遗留代码”很可能会在相当长的一段时间内正常工作,即使您什么都不修改。
只有在一个块中分配的空间超过2 Gb时,才会中断。或者当你要比较两个不相关的指针时,它们彼此之间的距离超过2 Gb。
因为从技术上讲,比较不相关的指针是一种未定义的行为,所以你不会遇到那么多这样做的代码(但你永远不能确定)。
而且通常情况下,即使您总共需要超过2 2Gb,您的程序实际上也不会进行大于2 2Gb的单次分配。事实上,在Windows中,即使使用LARGEADDRESSAWARE,默认情况下也无法分配那么多内存。您需要打乱系统DLL,以获得大于2 2Gb的连续块
但是墨菲定律说,这种代码总有一天会崩溃,只是在你启用LARGEADDRESSAWARE之后很长一段时间,没有人会记得已经做过了。
https://stackoverflow.com/questions/2288728
复制相似问题