Link Map File中文直譯爲連接映射文件,它是在Xcode生成可執行文件的同時生成的連接信息文件,用於描述可執行文件的構造部分,包括了代碼段和數據段的分佈狀況。Xcode在生成可執行文件的時候默認狀況下不生成該文件,須要開發者手動設置Target --> Build Setting --> Write Link Map File爲YES:
這裏還能夠設置Link Map存放的位置,默認的位置爲:html
$(TARGET_TEMP_DIR)/$(PRODUCT_NAME)-LinkMap-$(CURRENT_VARIANT)-$(CURRENT_ARCH).txt
例如:ios
/Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/LinkMapTest-LinkMap-normal-x86_64.txt
開發者也能夠根據本身的須要自行設置該文件的位置。git
打開Link Map File,裏面包含了如下幾個部分:github
# Path: /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Products/Debug-iphonesimulator/LinkMapTest.app/LinkMapTest
Path是生成可執行文件的路徑。shell
# Arch: x86_64
Arch指代架構類型。架構
# Object files: [ 0] linker synthesized [ 1] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/LinkMapTest.app-Simulated.xcent [ 2] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/ViewController.o [ 3] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/main.o [ 4] /Users/zhanggui/Library/Developer/Xcode/DerivedData/LinkMapTest-ffnpzjkbsmhwvdcxorqbxpyvjtob/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/AppDelegate.o [ 5] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.1.sdk/System/Library/Frameworks//Foundation.framework/Foundation.tbd [6]/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.1.sdk/usr/lib/libobjc.tbd [7]/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.1.sdk/System/Library/Frameworks//UIKit.framework/UIKit.tbd
Object Files列舉了可執行文件裏全部的obj以及tbd。每一行表明對文件的編號。例如ViewController.o文件,其編號爲2。編號的具體做用稍後介紹。app
# Sections: # Address Size Segment Section 0x100001730 0x00000333 __TEXT __text 0x100001A64 0x0000002A __TEXT __stubs 0x100001A90 0x00000056 __TEXT __stub_helper 0x100001AE6 0x00000A27 __TEXT __objc_methname 0x10000250D 0x0000003C __TEXT __objc_classname 0x100002549 0x0000086D __TEXT __objc_methtype 0x100002DB6 0x0000007A __TEXT __cstring 0x100002E30 0x00000182 __TEXT __entitlements 0x100002FB4 0x00000048 __TEXT __unwind_info 0x100003000 0x00000010 __DATA __nl_symbol_ptr 0x100003010 0x00000010 __DATA __got 0x100003020 0x00000038 __DATA __la_symbol_ptr 0x100003058 0x00000010 __DATA __objc_classlist 0x100003068 0x00000010 __DATA __objc_protolist 0x100003078 0x00000008 __DATA __objc_imageinfo 0x100003080 0x00000BE8 __DATA __objc_const 0x100003C68 0x00000010 __DATA __objc_selrefs 0x100003C78 0x00000008 __DATA __objc_classrefs 0x100003C80 0x00000008 __DATA __objc_superrefs 0x100003C88 0x00000008 __DATA __objc_ivar 0x100003C90 0x000000A0 __DATA __objc_data 0x100003D30 0x000000C0 __DATA __data
單從字面含義理解:每一個Section包含了Address、Size、Segment以及Section。介紹以前,這裏先簡單介紹一下Mach-O文件。
上面第一部分的Path是可執行文件的路徑,使用iTerm進去到該文件夾,而後使用file命令便可查看該文件的類型:iphone
file LinkMapTest
輸出結果爲:函數
LinkMapTest: Mach-O 64-bit executable x86_64
能夠知道該文件是一個Mach-O格式的文件,它是iOS系統應用執行文件格式。Mach-O文件中的虛擬地址最終會被映射到物理地址上,這些地址會被分爲不一樣的段類型:_ _ TEXT 、_ _ DATA以及_ _ LINKEDIT等。各個段的含義以下:學習
Segment又被劃分紅了不一樣的Section,不一樣的Section存儲了不一樣的信息,例如 _ _ objc _ methname 爲方法的名稱。
再回顧上面的Sections,Address是起始位置、Size是大小、Segment是段、Section。
# Address Size File Name 0x100001730 0x0000003C [ 2] -[ViewController viewDidLoad] 0x100001770 0x00000092 [ 3] _main 0x100001810 0x00000080 [ 4] -[AppDelegate application:didFinishLaunchingWithOptions:] 0x100001890 0x00000040 [ 4] -[AppDelegate applicationWillResignActive:] 0x1000018D0 0x00000040 [ 4] -[AppDelegate applicationDidEnterBackground:] 0x100001910 0x00000040 [ 4] -[AppDelegate applicationWillEnterForeground:] 0x100001950 0x00000040 [ 4] -[AppDelegate applicationDidBecomeActive:] 0x100001990 0x00000040 [ 4] -[AppDelegate applicationWillTerminate:] 0x1000019D0 0x00000020 [ 4] -[AppDelegate window] 0x1000019F0 0x00000040 [ 4] -[AppDelegate setWindow:] 0x100001A30 0x00000033 [ 4] -[AppDelegate .cxx_destruct] 0x100001A64 0x00000006 [ 5] _NSStringFromClass 0x100001A6A 0x00000006 [ 7] _UIApplicationMain 0x100001A70 0x00000006 [ 6] _objc_autoreleasePoolPop 0x100001A76 0x00000006 [ 6] _objc_autoreleasePoolPush 0x100001A7C 0x00000006 [ 6] _objc_msgSendSuper2 0x100001A82 0x00000006 [ 6] _objc_retainAutoreleasedReturnValue 0x100001A88 0x00000006 [ 6] _objc_storeStrong 0x100001A90 0x00000010 [ 0] helper helper 0x100001AA0 0x0000000A [ 5] _NSStringFromClass 0x100001AAA 0x0000000A [ 6] _objc_autoreleasePoolPop 0x100001AB4 0x0000000A [ 6] _objc_autoreleasePoolPush 0x100001ABE 0x0000000A [ 6] _objc_msgSendSuper2 0x100001AC8 0x0000000A [ 6] _objc_retainAutoreleasedReturnValue 0x100001AD2 0x0000000A [ 6] _objc_storeStrong 0x100001ADC 0x0000000A [ 7] _UIApplicationMain 0x100001AE6 0x0000000C [ 2] literal string: viewDidLoad . . .
根據Sections的起始地址,能夠將Symbols分爲Sections個數的組,例如0x100001730到0x100001A64之間,就是 _ _ test代碼區。
Symbols包含的信息有:
# Dead Stripped Symbols: # Size File Name <<dead>> 0x00000018 [ 2] CIE <<dead>> 0x00000018 [ 3] CIE <<dead>> 0x00000006 [ 4] literal string: class <<dead>> 0x00000008 [ 4] literal string: v16@0:8 <<dead>> 0x00000018 [ 4] CIE . . .
在使用linkmap計算內存佔比的時候,不要把Dead Stripped Symbols計算在內,由於它們是連接器認爲無用的符號,連接的時候不會記入。
上面即是對Link map file作了簡單的介紹。
花了兩天的時間,根據對Link Map File的學習,使用Ruby寫了一個腳本文件,能夠方便地統計出指定Link Map File中的組件或者tbd佔用內存大小,相似:
AppDelegate.o 8.50KB ViewController.o 735B LinkMapDemo.app-Simulated.xcent 386B main.o 192B linker synthesized 128B libobjc.tbd 120B Foundation.tbd 24B UIKit.tbd 24B 總大小爲(僅供參考):10.07KB
想了解更多能夠訪問itools