Hon*_*gli 15 c++ memory-management elf dynamic-linking low-level
我有一个用C++编写的服务器应用程序.启动后,它在x86 Linux上使用大约480 KB的内存(Ubuntu 8.04,GCC 4.2.4).我认为480 KB是一个过多的内存:服务器甚至没有做任何事情,没有客户端连接到服务器.(另请参阅下面的评论,其中我解释了为什么我认为480 KB是大量内存.)服务器在初始化期间唯一做的事情就是产生一个或两个线程,设置几个套接字,以及其他简单的东西.非常记忆密集.
请注意,我在谈论实际内存使用情况,而不是VM大小.我通过在空闲笔记本电脑上启动我的服务器的100个实例来测量它,并在启动服务器实例之前和之后用"免费"测量系统内存使用情况.我已经考虑了文件系统缓存和类似的东西.
经过一些测试后,看起来C++运行时中的某些东西会导致我的服务器使用这么多内存,即使服务器本身没有做任何事情.例如,如果我插入
getchar(); return 0;
Run Code Online (Sandbox Code Playgroud)
之后
int main(int argc, char *argv[]) {
Run Code Online (Sandbox Code Playgroud)
然后每个实例的内存使用量仍为410 KB!
我的应用程序仅依赖于Curl和Boost.我有很多C编程经验,我知道C库在使用之前不会增加内存消耗.
我发现的其他事情:
我的结论如下:
我记得几年前关于C++动态链接器问题的一些KDE讨论.之后的Linux C++动态链接器导致KDE C++应用程序启动时间慢,内存消耗大.据我所知,这些问题已在C++运行时修复.但类似的东西可能是我所看到的过度记忆消耗的原因吗?
来自gcc /动态链接专家的答案非常感谢.
对于那些好奇的人,有问题的服务器是Phusion Passenger的日志记录代理:https://github.com/FooBarWidget/passenger/blob/master/ext/common/LoggingAgent/Main.cpp
C运行时分配的内存多于您的进程实际用作正常操作的一部分.这是因为在内核级别分配内存非常慢,并且只能在页面大小的块中完成(x86盒子上的页面大小通常为4kb,但它可能更大,在x64机器上通常为8kb或更多).
此外,当C运行时接收到它不能满足的分配请求时,它将经常分配超过必要的次数,以便在大多数时间内去除进入内核的费用.
最后,如果您正在使用boost goodies,它们可能依赖于某些STL组件,例如std::vector.这些组件为使用的元素分配空间std::allocator<T>,在某些情况下将再次分配比实际使用的空间更多的空间.(特别是基于节点状结构std::map,std::set以及std::list通常这样做是为了把列表或树的节点放在同一个内存页)
长话短说:别担心.任何想象力(至少现在)都不会占用半兆内存,而且大部分内存可能只是在分摊动态分配功能的使用.写下您的实际服务器,如果它使用了太多内存,那么请查看减少内存使用量的方法.
编辑:如果你正在使用的boost组件碰巧是asio,并且你正在使用套接字,你也应该知道为了维护套接字缓冲区而消耗了一些内存.