为什么堆分配比堆栈分配使用大量内存?
Why heap allocation uses a lot of memory than stack allocation?
我想知道为什么堆栈分配使用的内存比堆分配少?这个分配的差距真的很大。当我使用堆栈时。它消耗大约 77MB,但是当我使用堆分配时。它消耗约 880MB。没有内存泄漏(我猜),因为在我删除这个对象后内存 return 完全(回到小于 1KB 就像调用这个函数之前一样)。
这里是堆栈分配~77 MB
void LoadZone() //this fuction is called over 700 times
{
FILE* file; //this file contains data in binary (~54KB)
std::string filepath = "./map/" + std::to_string(MapId); //private member int MapId
errno_t e = fopen_s(&file, filepath.c_str(), "rb");
fread(&XLength, 1, sizeof(short), file); //private member short XLength
fread(&YLength, 1, sizeof(short), file); //private member short YLength
MapGrid.reserve(YLength); //private member : MapGrid is std::vector<std::vector<GridPos>>
for (short y = 0; y < YLength; ++y)
{
//GridPos contains short X,Y char Value
std::vector<GridPos> data;
data.reserve(XLength);
for (short x = 0; x < XLength; ++x)
{
data.emplace_back(x, y, (char)std::getc(file));
}
MapGrid.push_back(data);
}
fclose(file);
}
这是堆分配~880 MB
void LoadZone() //this fuction is called over 700 times
{
FILE* file; //this file contains data in binary (~54KB)
std::string filepath = "./map/" + std::to_string(MapId); //private member int MapId
errno_t e = fopen_s(&file, filepath.c_str(), "rb");
fread(&XLength, 1, sizeof(short), file); //private member short XLength
fread(&YLength, 1, sizeof(short), file); //private member short XLength
MapGrid.resize(YLength); //private member : MapGrid is std::vector<std::vector<GridPos*>>
for (short y = 0; y < YLength; ++y)
{
//GridPos contains short X,Y char Value
std::vector<GridPos*> data;
data.resize(XLength);
for (short x = 0; x < XLength; ++x)
{
data.push_back(new GridPos(x, y, (char)std::getc(file)));
}
MapGrid.push_back(data);
}
fclose(file);
}
堆分配都与某个最小值对齐(参见 _STDCPP_DEFAULT_NEW_ALIGNMENT__
)。例如,对于 x86_64 上的 glibc,它通常是 16。这基本上意味着堆总是分配至少 16 个字节,即使您要求一个字节。通常会浪费一些字节。因此,当您在堆栈上分配多个对象时,它们可以在内存中彼此相邻放置,但这不适用于堆分配的数据。
其次,堆需要一些内务处理数据。同样,对于 glibc 和 x86_64,这通常是 16 个字节。
总而言之,如果您分配一个 int
对象,它需要 4 个字节,那么堆会为此分配消耗 32 个字节的内存。您可以简单地对其进行基准测试(分配 100M 整数并测量最大 RSS)。
我想知道为什么堆栈分配使用的内存比堆分配少?这个分配的差距真的很大。当我使用堆栈时。它消耗大约 77MB,但是当我使用堆分配时。它消耗约 880MB。没有内存泄漏(我猜),因为在我删除这个对象后内存 return 完全(回到小于 1KB 就像调用这个函数之前一样)。
这里是堆栈分配~77 MB
void LoadZone() //this fuction is called over 700 times
{
FILE* file; //this file contains data in binary (~54KB)
std::string filepath = "./map/" + std::to_string(MapId); //private member int MapId
errno_t e = fopen_s(&file, filepath.c_str(), "rb");
fread(&XLength, 1, sizeof(short), file); //private member short XLength
fread(&YLength, 1, sizeof(short), file); //private member short YLength
MapGrid.reserve(YLength); //private member : MapGrid is std::vector<std::vector<GridPos>>
for (short y = 0; y < YLength; ++y)
{
//GridPos contains short X,Y char Value
std::vector<GridPos> data;
data.reserve(XLength);
for (short x = 0; x < XLength; ++x)
{
data.emplace_back(x, y, (char)std::getc(file));
}
MapGrid.push_back(data);
}
fclose(file);
}
这是堆分配~880 MB
void LoadZone() //this fuction is called over 700 times
{
FILE* file; //this file contains data in binary (~54KB)
std::string filepath = "./map/" + std::to_string(MapId); //private member int MapId
errno_t e = fopen_s(&file, filepath.c_str(), "rb");
fread(&XLength, 1, sizeof(short), file); //private member short XLength
fread(&YLength, 1, sizeof(short), file); //private member short XLength
MapGrid.resize(YLength); //private member : MapGrid is std::vector<std::vector<GridPos*>>
for (short y = 0; y < YLength; ++y)
{
//GridPos contains short X,Y char Value
std::vector<GridPos*> data;
data.resize(XLength);
for (short x = 0; x < XLength; ++x)
{
data.push_back(new GridPos(x, y, (char)std::getc(file)));
}
MapGrid.push_back(data);
}
fclose(file);
}
堆分配都与某个最小值对齐(参见 _STDCPP_DEFAULT_NEW_ALIGNMENT__
)。例如,对于 x86_64 上的 glibc,它通常是 16。这基本上意味着堆总是分配至少 16 个字节,即使您要求一个字节。通常会浪费一些字节。因此,当您在堆栈上分配多个对象时,它们可以在内存中彼此相邻放置,但这不适用于堆分配的数据。
其次,堆需要一些内务处理数据。同样,对于 glibc 和 x86_64,这通常是 16 个字节。
总而言之,如果您分配一个 int
对象,它需要 4 个字节,那么堆会为此分配消耗 32 个字节的内存。您可以简单地对其进行基准测试(分配 100M 整数并测量最大 RSS)。