2

我的问题是我有一个无法修改的 32 位 DLL。在正常操作下,DLL 有时可能需要大约 1.5 gigs 左右的内存。

当我使用 C++/非托管代码测试程序时,DLL 只会在大约 2 gigs 时耗尽内存。这是预期的,因为这是 32 位进程可用的最大大小。因此,DLL 在正常操作下运行良好。

从本身占用大约 250 MB 的 C# 应用程序 IP/调用 DLL 时,当整个进程达到大约 1.4 gigs 时,DLL 会出错。我的问题是 P/Invoke 是否为 32 位进程提供了更少的内存供使用?有什么办法可以给它更多吗?

编辑:P/Invoked 函数实际上是从我的主要组件引用的 C# 程序集中调用的。不确定这是否以任何方式相关。

4

2 回答 2

3

The difference is probably because your managed program has greater needs than the unmanaged program. And so there are fewer resources left for your DLL. Programs can run out of memory even when there appears to be memory left. This happens when the address space is fragmented and the virtual memory allocator cannot find a large enough contiguous block of memory to meet an allocation request.

There's not much you can do about that I suspect. I doubt you'll have much luck trying to make your managed process consume fewer resources. If you run on a 64 bit system and your process is large address aware then your process can access have 4GB of memory.

Marking your .net executable as LARGEADDRESSAWARE might well help. For details please refer to another SO question: How to make a .NET application "large address aware"? In summary you need to run the EDITBIN tool to mark your executable:

EDITBIN /LARGEADDRESSAWARE YourExeName.exe

Be aware though that on a 32 bit OS you are pretty much stuck with the 2GB limit. Yes you can boot your system with the /3GB switch but this is generally not to be advised.

The other obvious option would be to house the DLL in an out of process COM server. By putting it in a different process you could keep the .net runtime out of the process and leave as much space as possible for the hungry DLL.

于 2012-12-06T15:13:26.870 回答
1

这可能会发生,因为您的 c++ 应用程序设置了 LARGEADDRESSAWARE 选项而 c# 应用程序没有

在 c++ 应用程序中,它在这里定义-> 链接器-> 系统-> 启用大地址 = "Yes/LARGEADDRESSAWARE"

尝试添加以下构建后事件

call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
"$(DevEnvDir)..\..\vc\bin\EditBin.exe" "$(TargetPath)"  /LARGEADDRESSAWARE
于 2012-12-06T15:24:05.683 回答