gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:48:49 25 4
gpt4 key购买 nike

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com