问题背景

大型应用程序中包含成千上万个 C++ 对象,这些对象大小如何?有没有一些大对象很废?例如,在 OceanBase 0.4 开源版本中 Top 10 的大对象,最大的一个占 58MB 内存:

排序 大小  类名 
1 58,720,304 rootserver::ObRootTable2 
2 20,163,008 updateserver::ObUpdateServerMain 
3 20,153,152 updateserver::ObUpdateServer 
4 18,761,432 common::ObMergerSchemaManager 
5 16,778,576 updateserver::ObUpsSlaveMgr 
6 8,147,136 chunkserver::ObChunkServerMain 
7 8,142,344 chunkserver::ObChunkServer 
8 7,513,576 chunkserver::ObChunkMerge 
9 7,492,928 chunkserver::ObTabletMergerV2 
10 6,308,720 mergeserver::ObMergerGetRequest

统计方法

下面以 debug 模式编译的 mergeserver 中的对象统计为例说明统计方法

nm mergeserver | grep  " V _ZTIN9" | awk '{ printf "%s\n", $3}' | c++filt |  awk '{ printf "%s\n", $3}' | sed '/</d' | awk '{printf "p sizeof(%s)\n", $1}' > t_merge.txt

利用gdb脚本计算sizeof:

$gdb mergeserver
(gdb) set logging on
(gdb) set logging file r_merge.txt
(gdb) source t_merge.txt

将输出导入到 r_merge.txt,如果遇到部分对象找不到,打开 t_merge.txt 稍微编辑一下,删掉对应对象,重新 source t_merge.txt。

生成结果报告

paste r_merge.txt t_merge.txt | awk '{printf "%s %s\n", $3, $5}' > merge.txt

最后,把 merge.txt 导入到 excel 做一下排序,搞定。