当只使用600 MB内存时,调整QByteArray的大小会抛出std::bad_alloc



我是Qt的新手,需要加载和处理一些大文件。相反,我的记忆力正在耗尽。以下代码说明了我的问题:

QByteArray mem;
for(int i=1; i<=20; ++i)
{
    std::cout << "eating " << (i * 100) << "MB";
    mem.resize(i * 100 * 1024 * 1024);
}

当它达到600MB时,我得到了std::bad_alloc。这真的不应该发生。有增加堆大小的秘密开关吗?

我在Windows上使用Qt 5.0.2和Visual C++10.0 x86编译器。

AFAIK QByteArray分配一个连续的内存块。虽然您的应用程序可能仍有大量可用的虚拟内存,但很有可能由于内存管理器没有足够大的连续内存块,因此分配给阵列的当前内存块无法进一步扩展。

如果你需要处理一些大文件,而不是分配内存并将它们加载到一个块中,我建议你查看内存映射到文件中的"视口"并以这种方式处理它。根据文件的大小,您可能能够将整个文件内存映射到一个块中的内存中。这在Windows上也比逐字节加载文件更高效,因为它利用虚拟内存系统来分页相关文件。

在Windows上,32位进程可以拥有2GB的堆内存。如果此内存不包含足够大的连续块来处理Bytearray,则会遇到错误的分配异常。

MSVC知道/LARGEADDRESSAWARE(处理大地址)和/HEAP(设置堆大小)链接器选项。

您可以检查这些更改是否会影响您可以一次分配的字节数。

在我的x64计算机上,一个在MSVC2012上使用/machine:X86编译的可执行文件为>=1200MB的单个分配抛出了一个错误的分配异常。

如果我将/LARGEADDRESSAWARE添加到Linker命令行,程序将继续,直到eating 2100MB之后崩溃。

如果我改为使用/MACHINE:X64进行编译,那么进程会将块分配到8000MB,没有任何异常(可能更多,但我只测试了8GB)。

最新更新