gpt4 book ai didi

c# - .Net 处理非托管内存的方式是否不同于 C++ 运行时/二进制可执行文件?

转载 作者:行者123 更新时间:2023-11-30 14:27:02 25 4
gpt4 key购买 nike

使用 p/invoke 与具有大量静态数据分配的 Fortran 库交互的 .Net 应用程序无法加载库,当它远低于 Windows 上的 2 GB 静态数据限制时。我通过 p/invoke 成功加载的最大静态代码大小约为 1 GB。如果我编写一个加载库的简单 C 程序,我可以加载最大 1.9 GB 的静态数据。两个测试应用程序都是 32 位的。

托管应用程序尝试通过失败的 LoadLibrary 加载库,并且从 Marshal.GetLastWin32Error 返回的错误消息是“没有足够的存储空间可用于处理此命令。” CLR 处理非托管库的静态内存分配的方式与 C++ 运行时为二进制可执行文件提供的方式有区别吗?

最佳答案

你在 C 程序中也没有太多保证,它只需要一个糟糕的注入(inject) DLL 加载到一个基地址,它将可用地址空间一分为二,操作系统再也找不到一个足够大的洞来适合那个巨大的部分。

在 .NET 程序中更糟糕的是,在您的 pinvoke 调用开始运行时,它已经加载了大量代码和数据。例如至少 10 个堆。最大的漏洞一般约为 650-750 兆字节,但只是在启动后立即出现。 SysInternals 的 VMMap 实用程序可以向您展示这片土地的布局。

要使洞变大,您几乎无能为力。确保您的 .NET 版本足够新,以便它在 64 位版本的 Windows 上获得 4 GB 的地址空间。您的 Fortran DLL 需要是/LARGEADDRESSAWARE 才能工作。重构 Fortran 代码以使其从堆中分配肯定是您不想做的事情。是时候开始构建它的 64 位版本了,这很简单。

关于c# - .Net 处理非托管内存的方式是否不同于 C++ 运行时/二进制可执行文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34007534/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com