c#调用内存消耗大的本机代码DLL (Delphi)后内存不足

本文关键字:DLL Delphi 内存不足 本机代码 内存 调用 | 更新日期: 2023-09-27 18:08:23

我有一个c#应用程序,它做了一些零碎的事情,但它执行的主要任务是由它调用的Delphi DLL完成的。

这个Delphi DLL占用了大量内存,为了提高速度,它需要在本地缓存大量db信息。我很高兴它没有泄漏,因为当代码在Delphi中运行时,FastMM4没有报告任何内存泄漏。

我开始遇到问题,然而,当控制返回到c#。c#代码试图对Delphi应用程序的结果进行一些计算(所有结果都通过DB封送)。这些计算通常涉及100万左右的双精度,所以内存使用并不极端,但是代码总是返回内存不足的异常。

我假设Delphi代码中的FastMM4仍然没有将释放的内存返回给Windows(因此可用于c#代码),因此该进程仍在使用它的最大32位内存分配,c#在需要时无法获得更多。

那么,我如何让Delphi使用(和释放)的内存再次被c#代码使用?我想我们可能需要做以下其中一件事:

  • 从c#端强制卸载Delphi DLL(我的同事不认为这会起作用,因为他认为它只会卸载代码而不是堆上使用的内存)-可能是LoadLibrary/FreeLibrary?
  • 在Delphi DLL结束时调用释放内存回Windows(我之前尝试过SetWorkingProcessSetSize,但似乎没有做任何事情,我应该使用不同的调用吗?)
  • 将Delphi DLL封装在c# DLL中,并在不同的AppDomain中调用它(从样式的角度来看,我不喜欢这样,因为我们正在创建包装器,只是为了容纳包装器。
  • 还有什么我错过的吗?

c#调用内存消耗大的本机代码DLL (Delphi)后内存不足

从c#端强制卸载Delphi DLL(我的同事不认为这会起作用,因为他认为它只会卸载代码而不是堆上使用的内存)-可能是LoadLibrary/FreeLibrary?

这就行了。当DLL卸载时,FastMM将完成并返回它保留和提交的内存。

我要做的一件事是在调用你的库之前调用GC.Collect . . net知道当更多的托管内存被请求时该怎么做,并自动调用收集器,但是它不知道你在本机代码中做什么,所以会有很多不必要的内存分配。

我也会从32位体系结构转移。这并不是说你用完了内存,而是你用完了连续的足够大的内存来满足你在Delphi中要做的任何事情。一个更大的虚拟地址空间将为你解决这个问题,而且在过去的6年里,没有一个处理器不是64位的。是时候迈出那些害羞的步伐,走向我们面前的光明未来了。