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

时间:2015-10-13 08:43:50

标签: 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()));
            }

谢谢。

1 个答案:

答案 0 :(得分:0)

对于第一部分,无论什么曾经malloc&#39; ed留下了mallaoc&ed; ed。原因是malloc()从操作系统获取内存的方式,即增加堆最大地址。因此,要再次发布它,您必须确保不再有任何地址的引用,否则会出现段错误。

现在有一种方法可以解决 工作,mmap()找到使用mmap()的分配器,或者在MS中调用的任何分配器说话。确保它可以使用munmap()

之类的内容再次发布

在memmapped地址中分配您的数据,并确保在取消映射之前不会对其进行任何引用。

PS。 也像@JSF说使用LargeAddressAware编译并在你的操作系统上启用3GB。 并且确保即使在32位系统上也至少有4GB RAM,操作系统会使用一些用户无法访问的内存。即使每个程序只能访问3GB,但仍然可以非常快地加入3GB以上。