我的问题是我有一个无法修改的32位DLL。在正常操作下,DLL有时可能需要大约1.5 GB的内存。
当我使用C ++ /非托管代码测试程序时,DLL只会在大约2演出时内存不足。这是预期的,因为这是32位进程可用的最大大小。因此,DLL在正常操作下运行良好。
当我从C#应用程序调用DLL时,该应用程序本身需要大约250 MB,当整个进程达到大约1.4 gigs时,DLL会出错。我的问题是P / Invoke是否为32位进程提供了更少的内存?有什么方法可以给它更多吗?
编辑:P / Invoked函数实际上是从我的主要assumbly引用的C#程序集中调用的。不确定这是否与任何方式相关。
答案 0 :(得分:3)
差异可能是因为您的托管程序比非托管程序有更多需求。因此,为您的DLL留下的资源更少。即使存在剩余内存,程序也可能会耗尽内存。当地址空间碎片化并且虚拟内存分配器找不到足够大的连续内存块来满足分配请求时,就会发生这种情况。
我怀疑你无能为力。我怀疑你试图让你的托管进程消耗更少的资源会有很多运气。如果您在64位系统上运行并且您的进程具有大地址感知功能,那么您的进程可以访问具有4GB内存。
将.net可执行文件标记为LARGEADDRESSAWARE
可能会有所帮助。有关详细信息,请参阅另一个SO问题:How to make a .NET application "large address aware"?总之,您需要运行EDITBIN
工具来标记可执行文件:
EDITBIN /LARGEADDRESSAWARE YourExeName.exe
请注意,在32位操作系统上,你几乎要坚持2GB的限制。是的,您可以使用/ 3GB开关启动系统,但通常不建议这样做。
另一个明显的选择是将DLL存放在进程外的COM服务器中。通过将它放在不同的进程中,您可以将.net运行时保留在进程之外,并为饥饿的DLL留出尽可能多的空间。
答案 1 :(得分:1)
这可能会发生,因为你的c ++ aplication设置了LARGEADDRESSAWARE选项并且c#app没有
在c ++ app中,它是在这里定义的 - >连接体 - >系统 - >启用大地址=“是/ LARGEADDRESSAWARE”
尝试添加以下帖子构建事件
call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
"$(DevEnvDir)..\..\vc\bin\EditBin.exe" "$(TargetPath)" /LARGEADDRESSAWARE