最大 malloc 大小低于预期
max malloc size lower than expected
这是一个检查最大malloc大小的简单程序:
#include <iostream>
std::size_t maxDataSize = 2097152000; //2000mb
void MallocTest(void*& ptr)
{
while (1)
{
ptr = malloc(maxDataSize);
if (ptr)
{
std::cout << "Malloc success: " << maxDataSize << std::endl;
return;
}
maxDataSize -= 1024;
if (maxDataSize <= 0)
{
return;
}
}
}
int main()
{
void* ptr = nullptr;
MallocTest(ptr);
if (ptr)
{
free(ptr);
}
system("pause");
return EXIT_SUCCESS;
}
我使用Windows 10 x64和Visual Studio 2017。当我运行该程序时,我成功获得了~1300mb的malloc调用。该程序是使用32位架构(发布模式(构建的,因此理论上内存限制等于2GB。有什么东西会导致内存碎片吗?为什么我不能分配超过 ~1300mb ?
注意:这个答案的大部分是在OP指示他们正在使用什么操作系统之前写的。这些概念仍然有效,但具体情况可能有所不同。
您说您的操作系统是 32 位的,实际上一个好的32 位实现将有 2 GB 的硬限制,因为大于PTRDIFF_MAX
的对象有很多细微的问题,在使用它们时很容易导致未定义的行为,并触发处理指针算术的编译器错误。但是,您已经达到了一些较低的限制因素。
在 Linux 上,当 32 位进程在64 位内核上运行时,32 位进程的虚拟地址空间限制在大多数 arch 上为 3 GB,在某些架构上为 2 GB,某些进程的虚拟地址空间限制为 4 GB。但是,在此空间中,已经映射了许多内容,这些内容使地址空间碎片化并限制任何连续范围的长度。这包括程序本身,如果它是动态链接的,则包括动态链接器及其使用的任何共享库。
如果您的程序不是构建为 PIE(与位置无关的可执行文件(,则它在 Linux/x86 上的默认基址为 128 MB。这会拆分地址空间的前 128 MB,因为无法与连续的上部一起使用。库的加载通常略低于地址空间上限,从该端分离出一些库,但可能不会太多。ASLR(地址空间布局随机化(可能会将它们向下移动一点,但主线内核不会这样做太多,以避免对已经非常有限的地址空间进行严重碎片化。一些为额外强化而修补的内核可能会随机化更多。
最终,大型连续分配(大于半 GB 左右,甚至可能小于此(在 32 位系统上无法可靠地提供。如果需要它们,则可能需要使用64位系统。但更好的选择可能是找出不需要连续分配的备用数据结构,甚至不需要处理不适合内存的数据。
- 如果没有malloc,链表实现将失败
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- c++r值引用应用于函数指针
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 如何修复函数样式强制转换或类型构造的预期"("?
- malloc() 可能出现内存泄漏
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 如何仅使用对象名称打印特定于对象的成员
- 相当于LocaleMatcher的ICU4C
- 等<thing>效于char32_t
- 为什么我的 std::ref 无法按预期工作?
- 类似于strcat()的函数出现问题
- '||'之前的预期主要表达
- 标记 '","' 之前的预期主表达式
- 将鼠标悬停在问题上时与预期">"相关的代码错误
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 最大 malloc 大小低于预期
- C++:读取.BMP文件时出现问题;文件结束时间早于预期
- 在malloc分配的内存之外使用指针的预期行为