.Net 处理非托管内存的方式是否不同于 C++ runtime/binary 可执行文件?
Does .Net handle unmanaged memory differently than a C++ runtime/binary executable?
使用 p/invoke 与具有大量静态数据分配的 Fortran 库交互的 .Net 应用程序无法加载库,当它远低于 [=18 上的 2 GB 静态数据限制时=].我通过 p/invoke 成功加载的最大静态代码大小约为 1 GB。如果我编写一个加载库的简单 C 程序,我可以加载最大 1.9 GB 的静态数据。两个测试应用程序都是 32 位的。
托管应用程序尝试通过 LoadLibrary 加载库失败,并且从 Marshal.GetLastWin32Error 返回的错误消息是 "not enough storage is available to process this command."CLR 处理非托管库静态内存分配的方式与. C++ 运行时将提供什么二进制可执行文件?
你在 C 程序中也没有太多保证,它只需要一个糟糕的注入 DLL 加载到一个基地址,它将可用地址 space 一分为二, OS 再也找不到足够大的洞来容纳那巨大的部分了。
在 .NET 程序中更糟糕的是,当您的 pinvoke 调用开始到 运行 时,它已经加载了大量代码和数据。例如至少 10 个堆。最大的漏洞一般约为 650-750 兆字节,但只是在启动后立即出现。 SysInternals 的 VMMap 实用程序可以向您展示这片土地的布局。
要使洞变大,您无能为力。确保您的 .NET 版本足够新,以便它在 Windows 的 64 位版本上获得 4 GB 地址 space。您的 Fortran DLL 需要是 /LARGEADDRESSAWARE 才能工作。重构 Fortran 代码以使其从堆中分配肯定是您不想做的事情。是时候开始构建它的 64 位版本了,这很简单。
使用 p/invoke 与具有大量静态数据分配的 Fortran 库交互的 .Net 应用程序无法加载库,当它远低于 [=18 上的 2 GB 静态数据限制时=].我通过 p/invoke 成功加载的最大静态代码大小约为 1 GB。如果我编写一个加载库的简单 C 程序,我可以加载最大 1.9 GB 的静态数据。两个测试应用程序都是 32 位的。
托管应用程序尝试通过 LoadLibrary 加载库失败,并且从 Marshal.GetLastWin32Error 返回的错误消息是 "not enough storage is available to process this command."CLR 处理非托管库静态内存分配的方式与. C++ 运行时将提供什么二进制可执行文件?
你在 C 程序中也没有太多保证,它只需要一个糟糕的注入 DLL 加载到一个基地址,它将可用地址 space 一分为二, OS 再也找不到足够大的洞来容纳那巨大的部分了。
在 .NET 程序中更糟糕的是,当您的 pinvoke 调用开始到 运行 时,它已经加载了大量代码和数据。例如至少 10 个堆。最大的漏洞一般约为 650-750 兆字节,但只是在启动后立即出现。 SysInternals 的 VMMap 实用程序可以向您展示这片土地的布局。
要使洞变大,您无能为力。确保您的 .NET 版本足够新,以便它在 Windows 的 64 位版本上获得 4 GB 地址 space。您的 Fortran DLL 需要是 /LARGEADDRESSAWARE 才能工作。重构 Fortran 代码以使其从堆中分配肯定是您不想做的事情。是时候开始构建它的 64 位版本了,这很简单。