c++ - 如何减少默认的 C++ 内存消耗?

标签 c++ memory-management elf low-level dynamic-linking

我有一个用 C++ 编写的服务器应用程序。启动后,它在 x86 Linux(Ubuntu 8.04,GCC 4.2.4)上使用了大约 480 KB 的内存。我认为 480 KB 是过多的内存:服务器甚至还没有做任何事情,没有客户端连接到服务器。 (另请参阅下面的评论,我在其中解释了为什么我认为 480 KB 是很多内存。) 服务器在初始化期间所做的唯一事情就是生成一两个线程、设置一些套接字以及其他不太占用内存的简单事情。

请注意,我说的是真实内存使用情况,而不是 VM 大小。我通过在一台闲置的笔记本电脑上启动 100 个服务器实例并在启动服务器实例之前和之后使用“空闲”测量系统内存使用情况来测量它。我已经考虑了文件系统缓存和类似的东西。

经过一些测试,即使服务器本身没有做任何事情,C++ 运行时中的某些东西也会导致我的服务器使用这么多内存。例如,如果我插入

getchar(); return 0;

紧接着

int main(int argc, char *argv[]) {

那么每个实例的内存使用量仍然是 410 KB!

我的应用程序仅依赖于 Curl 和 Boost。我有相当多的 C 编程经验,而且我知道 C 库在我使用它们之前不会增加内存消耗。

我发现的其他东西:

  • 一个简单的 hello world C 应用会消耗大约 50 KB 的内存。
  • 一个简单的 hello world C 应用程序链接到 Curl,但不使用 Curl,也消耗大约 50 KB 的内存。
  • 一个简单的 hello world C++ 应用(无 Boost)消耗大约 100 KB 的内存。
  • 一个简单的 hello world C++ 应用程序包含一些 Boost header ,但实际上并未使用 Boost,它会消耗大约 100 KB 的内存。使用“nm”检查可执行文件时没有 Boost 符号。

因此我的结论如下:

  1. Gcc 会丢弃未使用的 Boost 符号。
  2. 如果我的应用使用 Boost,那么 C++ 运行时中的某些东西(可能是动态链接器)会导致它使用大量内存。但是什么?我如何找出这些东西是什么,我能做些什么?

我记得几年前关于 C++ 动态链接器问题的一些 KDE 讨论。当时的 Linux C++ 动态链接器导致 KDE C++ 应用程序的启动时间变慢和大量内存消耗。据我所知,这些问题已在 C++ 运行时中得到修复。但是,类似的原因会导致我看到的内存消耗过多吗?

非常感谢 gcc/动态链接专家的解答。

对于那些好奇的人,有问题的服务器是 Phusion Passenger 的日志代理:https://github.com/FooBarWidget/passenger/blob/master/ext/common/LoggingAgent/Main.cpp

最佳答案

C 运行时分配的内存比您的进程在正常操作中实际使用的内存要多。这是因为在内核级别分配内存非常慢,并且只能在页面大小的 block 中完成(页面大小在 x86 机器上通常为 4kb,但它可以更大,在 x64 机器上通常为 8kb 或更多)。

此外,当 C 运行时收到一个它无法满足的分配请求时,它通常会分配超出必要的内存,以消除大部分时间访问内核的开销。

最后,如果您使用的是 boost goodies,它们可能依赖于一些 STL 组件,例如 std::vector .这些组件使用 std::allocator<T> 为元素分配空间,在某些情况下,它会再次分配比实际使用更多的空间。 (尤其是像 std::mapstd::setstd::list 这样的基于节点的结构通常这样做是为了将列表或树的节点放在同一个内存页面上)

长话短说:不要担心这个。半兆内存在任何想象中都不算多(至少现在是这样),其中大部分可能只是摊销动态分配函数的使用。写下你的实际服务器,如果它使用太多内存,那么看看减少内存使用的方法。

编辑:如果您使用的 boost 组件恰好是 asio,并且您使用的是套接字,那么您还应该知道为了维护套接字的缓冲区而消耗了一些内存。

关于c++ - 如何减少默认的 C++ 内存消耗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4178530/

相关文章:

C++:跟踪耗时

c - GCC 为 Mersenne 程序输出非常大的可执行文件

c - 是否可以用 C 编写零成本的异常处理?

c - 为整个地址空间设置保护位

xcode - 检查 Swift 中的类对象计数

linux - 如何找到未满足的 ELF 依赖项?

python - 为 python 设置 RPATH 不起作用

android - Flutter C++ 内存分配导致光栅线程卡顿 - Android NDK Dart FFI

C++友元函数和私有(private)构造函数

c++ - 使用目标和调用方法?