内存管理在c++混合模式下的应用

Memory management in C++ mixed mode application

本文关键字:应用 模式 混合 管理 c++ 内存      更新时间:2023-10-16

我有一个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()

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

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