如何确定我的库中文本大小如此之大?

时间:2015-03-09 14:50:17

标签: android c++ boost android-ndk

我有一个使用Android NDK for ARM构建的共享库文件。那里还有一点JNI。这个SO文件链接到许多其他.a文件(我们自己构建的静态库作为依赖项)以及一些其他第三方静态库,例如boost。

我正在使用GCC 4.8并将STL与C ++ 11功能结合使用。

我对此做了一些自我研究。特别是,我遇到了这个帖子:
why my C++ output executable is so big?

这帮助我找出了一些要运行的命令,例如size

$ size libmine.so
   text    data     bss     dec     hex filename
13017993         201972   54120 13274085         ca8be5 libmine.so

不幸的是,除了要运行的命令之外,链接的SO问题在诊断方面对我没什么帮助(或许也许我对linux风格的开发没有足够的经验来可靠地使用信息) 。我不确定如何分析所产生的结果,以帮助我查明引起任何增长的代码区域,特定库或模板函数/类/等。

共享库本身是13MB,这是非常巨大的。我确实验证了我的.SO文件是"剥离",我猜这意味着没有调试符号。在这一点上,我不确定这是由于提升还是一些疯狂的模板实例化。如何确定导致共享库大规模增长的因素?

1 个答案:

答案 0 :(得分:0)

  

我没有答案。然而。只是分享我的快速&肮脏的oneliners所以你不必。 免责声明 表现糟糕但GoodEnough™。应该使用 Perl / Python / Haskell / ... 实用主义是关键字。

     

您需要为总结安排bc¹

从Andy Brown的评论开始,我用:

分析了我自己项目的二进制文件
  • 定义帮助函数以列出名称:

    function names() { nm -l -S --size-sort --radix=d -C "$@"; }
    

    删除-l(行号)以获得更高的性能(我不需要)

  • 以下单行显示重复的累计大小:

    for a in bin/*; do echo -e "$a\t$(names "$a" | \
         cut -d\   -f1-2 | sort | uniq -cd | \
         perl -ne '@a=split and print "" . (($a[0]-1) * $a[2]) . "\n"' | \
         paste -sd+ | bc)"; done
    
      

    这往往只显示弱符号。因为这里的实际值是重复的,我不确定这实际上意味着重复的大小计算为剥离的二进制文件大小

  • 符号类型的直方图:

    for a in bin/*; do names "$a" | awk '{print $3}'; done | sort | uniq -c | sort -rn
    
  • 按符号类型的符号总大小,按上一步骤中直方图的降频顺序排列:

    for a in bin/*; do names "$a" | awk '{print $3}'; done | \
        sort | uniq -c | sort -rn | \
        while read count type
        do 
            total=0
            for a in bin/*
            do 
                size=$(names "$a" | awk "\$3==\"$type\" {print \$2}" | paste -sd+ | bc)
                total=$(($total + $size))
                echo -e "$type\t$size\t$a"
            done
            echo -e "total:\t$total\ttotal bytes in $count symbols\n-------"
        done
    

我系统上的示例输出:

bin/tool1          208148
bin/liba.so        204463
bin/libcryptopp.so 166771
bin/tool2          211916
bin/tool3          204733
bin/testrunner     208271

46935   W
16173   V
10442   T
 1724   u
  574   d
  184   R
  158   B
   94   t
   49   r
   33   b
   13   D


W   1053961 bin/tool1
W   1030888 bin/liba.so
W   784518  bin/libcryptopp.so
W   1097729 bin/tool2
W   1031444 bin/tool3
W   1072752 bin/testrunner
total:  6071292 total bytes in 46935 symbols
-------
V   317146  bin/tool1
V   243869  bin/liba.so
V   368815  bin/libcryptopp.so
V   321841  bin/tool2
V   316629  bin/tool3
V   316947  bin/testrunner
total:  1885247 total bytes in 16173 symbols
-------
T   459075  bin/tool1
T   449020  bin/liba.so
T   610503  bin/libcryptopp.so
T   455224  bin/tool2
T   450630  bin/tool3
T   449234  bin/testrunner
total:  2873686 total bytes in 10442 symbols
-------
u   4912    bin/tool1
u   4136    bin/liba.so
u   448 bin/libcryptopp.so
u   5381    bin/tool2
u   4136    bin/tool3
u   4136    bin/testrunner
total:  23149   total bytes in 1724 symbols
-------

¹我知道它可以用纯粹的bash来完成,但它要么涉及在评估扩展中扩展整个流,要么编写更多的嵌套循环。我在这里更喜欢bc