c# - C++ 混合模式应用程序中的内存管理

标签 c# c++ .net memory memory-management

我有一个 x32 的混合模式应用程序。所以只有2G内存可用。应用程序处理一些大数据并在非托管堆中分配大约 1.5G。然后它释放分配的非托管内存而不会泄漏。但下一步是在托管模式下处理大约 1.5G。当分配了大约 200M 的托管内存时,尝试在 List 中添加元素时应用程序崩溃了。正如我所想,非托管堆管理器获取 1.5G 的内存,在其中分配对象,然后释放对象但不释放堆内存以供托管堆管理器访问。托管和非托管内存管理器如何共享进程的内存?我该如何解决这样的问题?

这是一个示例代码,在分配和释放非托管代码后尝试分配托管内存时抛出异常。它必须在 x32 中编译。为什么会这样?

            int size = 1024 * 1024 * 1024 / 2 / 10;

            char* * cppArray = new char*[size];

            for(int i = 0; i < size - 1; i++)
            {
                char *str = (char*)malloc(10 * sizeof(char));
                strcpy(str, "AAAAAAAAAA"); 
                cppArray[i] = str;
            }

            for(int i = 0; i < size - 1; i++)
            {
                char* str = cppArray[i];
                free(str);
            }

            delete[] cppArray;

            List<String^>^ pArray = gcnew List<String^>();

            size = 1024 * 1024 * 1024 / 2 / 7 / 2 / 2;

            for(int i = 0; i < size - 1; i++)
            {
                pArray->Add(gcnew String("AAAAAAAAAA" + i.ToString()));
            }

谢谢。

最佳答案

对于第一部分,任何曾经被 malloc'ed 的东西都会被 malloc'ed。原因是 malloc() 从操作系统获取内存的方式,即增加堆最大地址。因此,要再次释放它,您必须确保不再有对任何地址的引用,否则会出现段错误。

现在有一种可能可以解决这个问题的方法,即mmap()找到一个使用 mmap() 的分配器,或者它在 MS 语言中的任何名称。确保它可以使用 munmap() 之类的东西再次释放它。

在内存映射地址中分配您的数据,并确保在取消映射之前没有留下对它的引用。

附言。 也像@JSF 所说的那样,使用 LargeAddressAware 编译并在您的操作系统上启用 3GB。 并且即使在 32 位系统上也要确保你至少有 4GB 内存,操作系统使用了其中一些用户无法访问的内存。即使每个程序只能访问 3GB,加起来仍然非常快超过 3GB。

关于c# - C++ 混合模式应用程序中的内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33098016/

相关文章:

c++ - 找出非常大数的除法模

c++ - C++中的位 vector

c# - 如何将这些名称 "interpolate"转换为我要更新的方法/变量?

c# - 使用 SlimDX 从 RGBA 值创建纹理

c# - 从服务器 xamarin.android 收到的证书无效

c++ - 将 double 值乘以 10 时究竟发生了什么

java - 使用 aws lambda c# 裁剪图像(使用 Java 解决)

c# - LINQ Max() 函数执行速度超慢

c# - .NET 中的 Unicode 版本

.net - 是否有任何不需要安装Oracle Client的Oracle .NET数据提供程序?