问题背景
大型应用程序中包含成千上万个 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 做一下排序,搞定。