C# 在调用耗费大量内存的本机代码 DLL 后内存不足 (Delphi)
C# out of memory after calling a memory-hungry native-code DLL (Delphi)
我有一个 C# 应用程序,它执行一些零碎的操作,但它执行的主要任务是由它调用的 Delphi DLL 完成的。
此 Delphi DLL 占用大量内存,需要在本地缓存大量数据库信息以提高速度。我很高兴它没有泄漏,因为当代码在 Delphi.
中时,FastMM4 没有报告任何内存泄漏
我开始 运行 遇到问题,但是,当控件返回到 C# 时。 C# 代码尝试对 Delphi 应用程序的结果进行一些计算(所有结果都通过数据库编组)。这些计算通常涉及一百万左右的两倍,因此不会占用大量内存,但是代码会不断返回内存不足异常。
我假设 Delphi 代码中的 FastMM4 仍未将释放的内存返回给 Windows(因此可用于 C# 代码),因此该进程仍在使用它的最大值 32 -位内存分配和C#无法在需要时获得更多。
那么,如何让 Delphi 使用(和释放)的内存再次被 C# 代码使用?我想我们可能想要执行以下操作之一:
- 从 C# 端强制卸载 Delphi DLL(我的同事认为这行不通,因为他认为它只会卸载代码而不是堆上使用的内存) - 可能 LoadLibrary/FreeLibrary?
- 在Delphi DLL的末尾调用,将内存释放回Windows(我之前试过SetWorkingProcessSetSize,但似乎没有做任何事情,我应该使用不同的打电话?)
- 将 Delphi DLL 包装在 C# DLL 中并在不同的 AppDomain 中调用它(从样式的角度来看我不喜欢这样,因为我们创建包装器只是为了保存包装器。
- 我还有什么遗漏的吗?
Force an unload of the Delphi DLL from the C# side (my colleague doesn't think this will work, as he thinks it'll just unload the code rather than the memory used on the heap) - probably LoadLibrary/FreeLibrary?
这样就可以了。当 DLL 卸载时,FastMM 将完成并 return 它保留和提交的内存。
我会做的一件事是在致电您的图书馆之前先致电 GC.Collect
。 .NET 知道当请求的托管内存超过容量时该怎么做并自动调用收集器,但是它不知道您在本机代码中做什么,因此会分配大量不必要的内存。
我也会从 32 位架构转移。不是你 运行 内存不足,而是你 运行 连续内存不足,足以容纳你在 Delphi 中尝试做的任何事情。更大的虚拟地址 space 将为您解决这个问题,并且在过去 6 年中没有一款处理器不支持 64 位。是时候迈出那些害羞的脚步,迈向我们面前的光明未来了。
我有一个 C# 应用程序,它执行一些零碎的操作,但它执行的主要任务是由它调用的 Delphi DLL 完成的。
此 Delphi DLL 占用大量内存,需要在本地缓存大量数据库信息以提高速度。我很高兴它没有泄漏,因为当代码在 Delphi.
中时,FastMM4 没有报告任何内存泄漏我开始 运行 遇到问题,但是,当控件返回到 C# 时。 C# 代码尝试对 Delphi 应用程序的结果进行一些计算(所有结果都通过数据库编组)。这些计算通常涉及一百万左右的两倍,因此不会占用大量内存,但是代码会不断返回内存不足异常。
我假设 Delphi 代码中的 FastMM4 仍未将释放的内存返回给 Windows(因此可用于 C# 代码),因此该进程仍在使用它的最大值 32 -位内存分配和C#无法在需要时获得更多。
那么,如何让 Delphi 使用(和释放)的内存再次被 C# 代码使用?我想我们可能想要执行以下操作之一:
- 从 C# 端强制卸载 Delphi DLL(我的同事认为这行不通,因为他认为它只会卸载代码而不是堆上使用的内存) - 可能 LoadLibrary/FreeLibrary?
- 在Delphi DLL的末尾调用,将内存释放回Windows(我之前试过SetWorkingProcessSetSize,但似乎没有做任何事情,我应该使用不同的打电话?)
- 将 Delphi DLL 包装在 C# DLL 中并在不同的 AppDomain 中调用它(从样式的角度来看我不喜欢这样,因为我们创建包装器只是为了保存包装器。
- 我还有什么遗漏的吗?
Force an unload of the Delphi DLL from the C# side (my colleague doesn't think this will work, as he thinks it'll just unload the code rather than the memory used on the heap) - probably LoadLibrary/FreeLibrary?
这样就可以了。当 DLL 卸载时,FastMM 将完成并 return 它保留和提交的内存。
我会做的一件事是在致电您的图书馆之前先致电 GC.Collect
。 .NET 知道当请求的托管内存超过容量时该怎么做并自动调用收集器,但是它不知道您在本机代码中做什么,因此会分配大量不必要的内存。
我也会从 32 位架构转移。不是你 运行 内存不足,而是你 运行 连续内存不足,足以容纳你在 Delphi 中尝试做的任何事情。更大的虚拟地址 space 将为您解决这个问题,并且在过去 6 年中没有一款处理器不支持 64 位。是时候迈出那些害羞的脚步,迈向我们面前的光明未来了。