浅谈 LinkMap 检查每个类占用大小

LinkMap 文件是 Xcode 产生可执行文件的同时生成的链接信息,用来描述可执行文件的构造成分,包括代码段 __TEXT 和数据段 __DATA 的分布情况。只要设置 Project->Build Settings->Write Link Map FileYES,并设置 Path to Link Map Filebuild 完后就可以在设置的路径看到 LinkMap 文件了:

image.png

LinkMap 的路径:

/Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/XXXX-LinkMap-normal-arm64.txt

一份完整的 LinkMap 文件中包含了一下几个部分:

App的编译路径(#Path)

# Path: /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Products/Debug-iphoneos/XXXXapp/XXXX

App对应的架构(#Arch)

# Arch: arm64

Object files:

# Object files:
[  0] linker synthesized
[  1] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/Objects-normal/arm64/QMGameReport.o
[  2] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/Objects-normal/arm64/QMNewAnimationManager.o
[  3] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-boyphtjpmytnckgosnyjctscvngm/Build/Intermediates.noindex/XXXX.build/Debug-iphoneos/XXXX.build/Objects-normal/arm64/QMCocosAnimationView.o
...

第一部分列举可执行文件里所有链接的 .o 文件,以及每个文件的编号。

Sections:

# Sections:
# Address   Size        Segment Section
0x100004180 0x027ECF28  __TEXT  __text
0x1027F10A8 0x00005130  __TEXT  __stubs
0x1027F61D8 0x000048B4  __TEXT  __stub_helper
0x1027FAAA0 0x00131318  __TEXT  __const
0x10292BDC0 0x0018FFDF  __TEXT  __cstring
0x102ABBDA0 0x0001839E  __TEXT  __ustring
0x102AD413E 0x000EC936  __TEXT  __objc_methname
0x102BC0A74 0x00013E5F  __TEXT  __objc_classname
0x102BD48D3 0x00023F8A  __TEXT  __objc_methtype
0x102BF8860 0x00106C50  __TEXT  __gcc_except_tab
0x102CFF4B0 0x0004FF6C  __TEXT  __unwind_info
0x102D4F420 0x00000BBC  __TEXT  __eh_frame
0x102D50000 0x00001A30  __DATA  __got
0x102D51A30 0x00003620  __DATA  __la_symbol_ptr
0x102D55050 0x000003D8  __DATA  __mod_init_func
0x102D55428 0x00000008  __DATA  __mod_term_func
0x102D55430 0x000DFAC0  __DATA  __const
0x102E34EF0 0x00097920  __DATA  __cfstring
0x102ECC810 0x00006430  __DATA  __objc_classlist
0x102ED2C40 0x000000C0  __DATA  __objc_nlclslist
0x102ED2D00 0x00000958  __DATA  __objc_catlist
0x102ED3658 0x00000108  __DATA  __objc_nlcatlist
0x102ED3760 0x000012B8  __DATA  __objc_protolist
0x102ED4A18 0x00000008  __DATA  __objc_imageinfo
0x102ED4A20 0x0033CE60  __DATA  __objc_const
0x103211880 0x0003B238  __DATA  __objc_selrefs
0x10324CAB8 0x000000A0  __DATA  __objc_protorefs
0x10324CB58 0x00005F78  __DATA  __objc_classrefs
0x103252AD0 0x00004400  __DATA  __objc_superrefs
0x103256ED0 0x000126B0  __DATA  __objc_ivar
0x103269580 0x0003EA30  __DATA  __objc_data
0x1032A7FC0 0x000C89E0  __DATA  __data
0x1033709A0 0x00310E68  __DATA  __bss
0x103682000 0x00104C40  __DATA  __common

第二部分是可执行文件的段表,描述各个段在可执行文件中的地址和大小,段类型以及段名称。第一列是段的地址,第二列是段占用大小;第三列是段类型,代码段和数据段,数据类型分为两种不同类型,一种是 __TEXT,用于保存程序代码段经过编译后的机器码,另外一种是 __DATA 用于保存诸如全局变量或者局部变量;第四列是段名称,如 __text 段是可执行机器码,__cstring 段是字符串常量, __bss 表示未初始化的全局变量及局部静态变量,__const 表示的是对应的不可变的变量。当然这一切的数据都是文件占用空间,并不是运行时的占用空间。

Symbols:

# Symbols:
# Address   Size        File  Name
0x100004180 0x000002A4  [  1] -[QMGameReport initWithFrame:isNightMode:]
0x100004424 0x00000264  [  1] -[QMGameReport setConnerRadiusForBackgroundView]
0x100004688 0x00000034  [  1] _CGSizeMake
0x1000046BC 0x00000120  [  1] -[QMGameReport showInView:]
0x1000047DC 0x00000040  [  1] ___27-[QMGameReport showInView:]_block_invoke
0x10000481C 0x0000004C  [  1] ___copy_helper_block_
0x100004868 0x00000030  [  1] ___destroy_helper_block_
0x100004898 0x00000064  [  1] -[QMGameReport tapClick:]
0x1000048FC 0x000001F0  [  1] -[QMGameReport dismiss]
0x100004AEC 0x00000040  [  1] ___23-[QMGameReport dismiss]_block_invoke
0x100004B2C 0x0000004C  [  1] ___copy_helper_block_.276
0x100004B78 0x00000030  [  1] ___destroy_helper_block_.277
0x100004BA8 0x00000040  [  1] ___23-[QMGameReport dismiss]_block_invoke.279
0x100004BE8 0x0000004C  [  1] ___copy_helper_block_.282
0x100004C34 0x00000030  [  1] ___destroy_helper_block_.283
0x100004C64 0x00000AFC  [  1] -[QMGameReport setUpconfigItem]
0x100005760 0x0000005C  [  1] _CGRectMake
0x1000057BC 0x0000039C  [  1] -[QMGameReport reportAction:]
...

第三部分详细描述每个 .o 文件在每个段的分布情况,按第二部分 Sections 顺序展示。例如序号 1QMGameReport.o 文件,-[QMGameReport initWithFrame:isNightMode:] 方法在 __TEXTSegment 里面 .__textSection 段地址是 0x100004180,占用大小是116字节。根据序号累加每个 .o 文件在每个段的占用大小,从而计算出每个 .o 文件在可执行文件的占用大小,进而算出每个静态库、每个功能模块代码占用大小。

这里要注意的地方是,由于 __DATASegment 里面 .__bbsSection 是代表未初始化的静态变量,Size 表示应用运行时占用的堆大小,并不占用可执行文件,所以计算 .o 占用大小时,要排除这个段的 Size

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张戈的专栏

MySQL命令行工具:percona-toolkit安装使用初探

导读:percona-toolkit 源自 Maatkit 和 Aspersa 工具,这两个工具是管理 mysql 的最有名的工具,现在 Maatkit 工具已...

41370
来自专栏数据之美

Hive 常见问题与技巧【Updating】

1Q: 是否有像类似于phpmyadmin一样的hive查询客户端,能以界面的方式查询hive语句和导出数据 A: 有的,客户端的话可以使用squirre...

26170
来自专栏跟着阿笨一起玩NET

sql语句延时执行或者是指定时间执行

以下示例在晚上 10:20 (22:20) 执行存储过程 sp_update_job。

55010
来自专栏好好学java的技术栈

玩转springboot:整合mybatis实例

这篇文章讲解一下springboot整合mybatis,其实,springboot整合mybatis和springmvc整合mybatis并没有什么太大的区别,...

15930
来自专栏数据和云

【动手实践】Oracle 12.2 新特性:自动的列表分区创建

2017年来了,我们要启动新的学习征程了。在过去我们一直思考,什么样的内容能够更帮助大家了解和学习到有用的知识? 这个『动手实践』栏目就是这样一个改进和尝试吧,...

30260
来自专栏木头编程 - moTzxx

后台 配置页面功能设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

69140
来自专栏小怪聊职场

MySQL(一)|性能分析方法、SQL性能优化和MySQL内部配置优化

779100
来自专栏淡定的博客

sql注入入门学习(数字型)(连载中)

在MySQL中,表名存放在information_schema数据库下tables表table_name字段中、查表名我们主要用到的是TABLES表

35940
来自专栏大眼瞪小眼

面试-MySQL总结

2NF:每一个非主属性完全依赖于候选码(属性组的值能唯一的标识一个元组,但是其子集不可以)。

11330
来自专栏乐沙弥的世界

MySQL数据库数据迁移到SQLserver

15710

扫码关注云+社区

领取腾讯云代金券