Jas Laferriere
Jas Laferriere

Reputation: 824

Does P/Invoke provide less memory to the target DLL?

My issue is that I have a 32-bit DLL which I cannot modify. The DLL can sometimes require around 1.5 gigs of memory or so under normal operation.

When I use a C++/unmanaged code test program, the DLL will only go out of memory at about 2 gigs. This is expected as this is the maximum size available to a 32-bit process. Hence, the DLL runs fine under normal operation.

When I P/Invoke the DLL from a C# application that itself takes about 250 MB, the DLL errors out when the entire process reaches about 1.4 gigs. My question is does P/Invoke provide less memory for the 32 bit process to use? Is there some way I can give it more?

EDIT: The P/Invoked functions are actually called from a C# assembly referenced by my main assumbly. Not sure if this is relevant in any way.

Upvotes: 2

Views: 489

Answers (2)

David Heffernan
David Heffernan

Reputation: 613013

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.

Upvotes: 3

makc
makc

Reputation: 2579

this might happen because you c++ aplication has the LARGEADDRESSAWARE option set and the c# app doesnt

in c++ app it is defined here -> Linker->System-> Enable Large Addresses = "Yes/LARGEADDRESSAWARE"

try adding the following post build event

call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
"$(DevEnvDir)..\..\vc\bin\EditBin.exe" "$(TargetPath)"  /LARGEADDRESSAWARE

Upvotes: 1

Related Questions