【Android Linux內存及性能優化】三 進程內存的優化 - 數據段
本文接着
《【Android Linux內存及性能優化】(一) 進程內存的優化 - 堆段》
《【Android Linux內存及性能優化】(二) 進程內存的優化 - 棧段 - 環境變量 - ELF》
一、內存篇
1.3 進程內存優化
1.3.1 執行文件
1.3.1.5 數據段
1.3.1.5.1 .bss 與 .data 的區別
.bss : 主要用來保存未初始化或初始化爲0 的全局變量或靜態變量。
.data: 主要用來保存初始化不爲0 的全局變量或靜態變量。
爲什麼初值是否爲0 ,變得如此關鍵?
主要是因方loader 可以對初值爲0 的變量採取一定的優化措施。
loader 在加載進程時,會使用 mmap ,將 ELF 文件的數據段映射到內存中。
(1) 對於那些初值不爲0 的位於數據段的變量,其初始值必須保存在 .data節,需要佔用文件大小,當訪問這些變量時,便會觸發頁故障,將文件中對應的初值回載到內存中,完成初始化。
(2)對於那些初值爲0 的位於數據段的變量,不必將初始值保存到文件中,loader 只需要將這些段內存映射到一個全0 的頁面即可,這樣.bss 節並不佔據ELF 文件的空間。後續使用時,這些未始初化的變量會在堆段中分配內存,
還有一個差別就是,當程序讀取 data 節的數據時,系統會觸發頁故障,從而分配相應的物理內存。
當程序讀取 bss 節的數據時,內核會將其轉到一個全零的頁面,不會觸發頁故障,也不會爲其分配物理內存。
另外,在LInux 內核中,內存管理是以頁面爲單位,進程的數據段也必須是頁面對齊的,可問題是數據段做映射時,.data 往往無法正好填滿最後一個頁面,會剩餘一些字節,這時 loader 會試圖用 .bss 節的數據去填充它。
也正因如此,在最後的一個頁面中,.data 節填充後剩餘的字節使用 .bss 節數據進行填充,並將這些剩餘的字節全部填充爲0,
這同時會造成對最後一個頁面的寫操作,產生 dirty page。