我是一个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()));
}
谢谢。
答案 0 :(得分:0)
对于第一部分,无论什么曾经malloc&#39; ed留下了mallaoc&ed; ed。原因是malloc()
从操作系统获取内存的方式,即增加堆最大地址。因此,要再次发布它,您必须确保不再有任何地址的引用,否则会出现段错误。
现在有一种方法可以解决 工作,mmap()
找到使用mmap()
的分配器,或者在MS中调用的任何分配器说话。确保它可以使用munmap()
。
在memmapped地址中分配您的数据,并确保在取消映射之前不会对其进行任何引用。
PS。 也像@JSF说使用LargeAddressAware编译并在你的操作系统上启用3GB。 并且确保即使在32位系统上也至少有4GB RAM,操作系统会使用一些用户无法访问的内存。即使每个程序只能访问3GB,但仍然可以非常快地加入3GB以上。