为什么同一服务器的两个版本的行为不同?

时间:2011-11-12 23:35:04

标签: c++ linux memory-management virtual-memory

我用C ++写了一个小的geoip查找linux守护进程,我得到了两个不同的结果,我想知道为什么。

这是源代码:https://github.com/homer6/geoipd 我用valgrind检查了它是否有内存泄漏,而且没有。

我有两个Web服务器,它们都在Amazon EC2上运行相同的Ubuntu映像,并且都在负载均衡器后面,确保它们每个都获得大约相同的流量。我在两台服务器上安装了守护进程,我让它们在生产中运行了几天。

一切都按预期工作,但“ps aux”的输出对于两个实例略有不同。

服务器1:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME
1004     28889  0.0  6.7 640288 517692 ?       Ss   Nov09   0:03

服务器2:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME
1004     16587  0.0  6.7 574752 517688 ?       Ss   Nov09   0:02

我的问题是两部分:

  1. 为什么虚拟内存使用会有这么大的差异?
  2. 为什么常驻内存使用会有差异?
  3. 提前致谢...

    更新: 我记得在我第一次启动进程时检查VM大小。它们都是574752(或略低于575 MB),它们都具有相同的值。

2 个答案:

答案 0 :(得分:3)

VSZ大小没有意义,你可以忽略它。它可能是由许多奇怪的事情引起的。 (如果您想尝试追踪它,请比较两台机器上 cat / proc / pid / maps 的输出。

至于RSS为什么不同的几个字节,它是如此之小,我不会担心它。它可能只是由于堆栈随机化。

答案 1 :(得分:2)

从服务器1的地图中的这2个额外行:

7f003ed31000-7f003ed32000 ---p 00000000 00:00 0
7f003ed32000-7f003f532000 rw-p 00000000 00:00 0

似乎服务器1已为服务器2尚未分配的某个对象分配(但尚未初始化)内存。这不一定是坏事;每个内核最有可能正确处理内存,只是不同。

您可以运行size geoip_server.o以确保每个系统上的2个守护程序的 bss (未初始化的静态数据)相同:

[ 18:10 root@hozbox / ]# size geoip_server.o
   text    data    bss         dec         hex       filename
   77727   1088772 200003752   201170251   bfd9d4b   geoip_server.o

这些数字由我没有cmake 2.8.2组成,所以我无法编译你的代码

此外,您可以在每个系统上cat /proc/meminfo查看每个内核如何管理其内存的具体信息:

[ 18:10 root@hozbox / ]# cat /proc/meminfo
MemTotal:         443880 kB
MemFree:            7792 kB
Buffers:             788 kB
Cached:            24468 kB
SwapCached:        87512 kB
Active:           189460 kB
Inactive:         193316 kB
Active(anon):     178604 kB
Inactive(anon):   178956 kB
Active(file):      10856 kB
Inactive(file):    14360 kB
Unevictable:           0 kB
Mlocked:               0 kB
HighTotal:             0 kB
HighFree:              0 kB
LowTotal:         443880 kB
LowFree:            7792 kB
SwapTotal:       4816892 kB
SwapFree:        3856464 kB
Dirty:                12 kB
Writeback:             0 kB
AnonPages:        305332 kB
Mapped:             7812 kB
Shmem:                60 kB
Slab:              17628 kB
SReclaimable:       8712 kB
SUnreclaim:         8916 kB
KernelStack:        1320 kB
PageTables:         4592 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     5038832 kB
Committed_AS:    1910872 kB
VmallocTotal:     570424 kB
VmallocUsed:       32424 kB
VmallocChunk:     524124 kB
HardwareCorrupted:     0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       4096 kB
DirectMap4k:       19392 kB
DirectMap4M:      438272 kB

This research paper from the University of Alberta on Understanding Memory是一个非常好的读物,可能有助于解释为什么在2个不同系统上运行的同一进程的VSZ差异可能是正常的。


一些参考资料和资源:

procfs wiki page
Runtime Memory Measurement
Linux Kernel Documentation on /proc
https://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux

man proc

  

/proc/[pid]/maps
  包含当前映射的内存区域的文件   和他们的访问权限。格式为:

address           perms offset  dev   inode   pathname
08048000-08056000 r-xp 00000000 03:0c 64593   /usr/sbin/gpm
08056000-08058000 rw-p 0000d000 03:0c 64593   /usr/sbin/gpm
08058000-0805b000 rwxp 00000000 00:00 0 
40000000-40013000 r-xp 00000000 03:0c 4165    /lib/ld-2.2.4.so 
40013000-40015000 rw-p 00012000 03:0c 4165    /lib/ld-2.2.4.so
4001f000-40135000 r-xp 00000000 03:0c 45494   /lib/libc-2.2.4.so
40135000-4013e000 rw-p 00115000 03:0c 45494   /lib/libc-2.2.4.so
4013e000-40142000 rw-p 00000000 00:00 0 
bffff000-c0000000 rwxp 00000000 00:00 0 
     

其中“地址”是它占用的进程中的地址空间,   “ perms ”是一组权限,   “ offset ”是文件/中的偏移量,“ dev ”是   设备(主要:次要)和“ inode ”是   该设备上的inode。 0表示没有inode与之关联   内存区域,与BSS(未初始化数据)的情况一样。