1. 程式人生 > 實用技巧 >嵌入式Linux系統記憶體優化

嵌入式Linux系統記憶體優化

(都是自己敲出來的,想到哪裡寫到哪裡,面對的是有一定基礎的朋友,有問題、建議的朋友可以留言,我不定期答疑;可以隨便轉發,只求更多人知道)

(至2020已工作10年了,一直在忙著分析問題、解決問題,現在每解決一個問題就寫一篇,分享給有需要的人)

繼上一篇《Linux Userspace Kernelspace記憶體分佈》之後,在分析一下記憶體優化的方法。

https://www.cnblogs.com/tangtangworld/p/11738090.html

後面還有一篇程序空記憶體使用分佈進一步分析的方法,看後面有沒有時間,這幾天被幾個Kernel Panic絆住了,在分析net子系統的程式碼。(MTK的SDK到處是坑)

通過對/proc/meminfo的分析,初步看去可以優化的地方不多:

1,tmpfs:/tmp下檔案數目: Active(anon), Inactive(anon)

  • 先控制/tmp的大小,我們某產品的/tmp總大小最好情況下在19MB,平均在15MB。
  • 對每個檔案分析之後,控制在6MB大小,總過獲得13MB的記憶體,對總共只有125/256MB的產品來說還是很多的。
  • 記住要引入監控機制:通過Monitor來監控tmp下檔案的總大小,如果超過6MB,就記錄日誌,便於跟蹤定位。

2,各個程序開啟的檔案:Active(file), Inactive(file)

  • 很多檔案(配置檔案)開啟只是為了獲取資料,用完及時關閉。
  • 對檔案的使用基於流操作,不要全部讀到記憶體在進行處理。
  • 系統啟動完成之後進行drop cache操作,把使用完畢的檔案從cache裡面清掉。sync && echo 3 >/proc/sys/vm/drop_caches

3,程序:程序的堆、棧:Active(anon), Inactive(anon)

  分析程序中記憶體的分佈,嘗試回答下面的問題,之後對程序的記憶體進行優化。注意要對業務比較熟悉,記憶體優化就是減少不需要的操作,通過優化資料結構和演算法來達到目的。(後面可能會寫幾篇關於資料結構和演算法的心得)

  • 程式碼太多?(充斥著很多沒有用到的函式,還沒有捨得刪除掉)
  • 靜態、全域性變數多?(很多變數歷史原因不會再使用,或者長度遠超過實際最大使用數)
  • 動態申請得記憶體比較多?(申請了記憶體,常駐在程序中,通過優化流程、演算法可以及時釋放掉)
  • 棧記憶體用得比較多?(函式呼叫層級太深,太多、太大的區域性變數,可能導致棧空間用完,預設Linux最大棧空間是16MB)
  • 某一個庫中消耗的記憶體比較多?(庫中對記憶體的不合理使用)

下面以bash為例進行解說,首先看到的是size命令的輸出:

   text    data     bss     dec     hex filename
1127387   47356   40056 1214799  12894f /usr/bin/bash

 通過size命令可以看到bash的程式碼段、資料段、bss段的大小。

  • data是指全域性變數或者靜態變數,已經被初始化為非0;data段比較大,會導致ELF檔案較大,對image size比較敏感的嵌入式系統,需要注意控制data段的大小。
  • bss段是未被初始化的全域性變數或靜態變數,預設被初始化為0。

 程序的記憶體分為程式碼段、資料段、BSS段、heap、記憶體對映、stack,在0~3GB的虛擬地址空間上,依次由低地址到高地址非連續排列。

  • 通過看/proc/$pid/maps來分析程序記憶體的分佈,0x55d518a4000開始的是程式碼段、data段、BSS段,map成只讀、可執行、可寫三部分。
  • 緊接著是堆記憶體的分佈
  • 接下來是每個庫的分佈
  • 然後是棧的空間
root@VirtualBox# cat /proc/129473/maps
558d518a4000-558d518d1000 r--p 00000000 08:05 1835663                    /usr/bin/bash
558d518d1000-558d51982000 r-xp 0002d000 08:05 1835663                    /usr/bin/bash
558d51982000-558d519b9000 r--p 000de000 08:05 1835663                    /usr/bin/bash
558d519b9000-558d519bd000 r--p 00114000 08:05 1835663                    /usr/bin/bash
558d519bd000-558d519c6000 rw-p 00118000 08:05 1835663                    /usr/bin/bash
558d519c6000-558d519d0000 rw-p 00000000 00:00 0
558d51b9c000-558d51c41000 rw-p 00000000 00:00 0                          [heap]
7f971e273000-7f971e294000 rw-p 00000000 00:00 0
7f971e294000-7f971e297000 r--p 00000000 08:05 1837196                    /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
7f971e297000-7f971e29e000 r-xp 00003000 08:05 1837196                    /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
7f971e29e000-7f971e2a0000 r--p 0000a000 08:05 1837196                    /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
7f971e2a0000-7f971e2a1000 r--p 0000b000 08:05 1837196                    /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
7f971e2a1000-7f971e2a2000 rw-p 0000c000 08:05 1837196                    /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
7f971e2a2000-7f971e2a8000 rw-p 00000000 00:00 0
7f971e2bb000-7f971eb2b000 r--p 00000000 08:05 1837771                    /usr/lib/locale/locale-archive
7f971eb2b000-7f971eb2e000 rw-p 00000000 00:00 0
7f971eb2e000-7f971eb53000 r--p 00000000 08:05 1837188                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f971eb53000-7f971eccb000 r-xp 00025000 08:05 1837188                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f971eccb000-7f971ed15000 r--p 0019d000 08:05 1837188                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f971ed15000-7f971ed16000 ---p 001e7000 08:05 1837188                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f971ed16000-7f971ed19000 r--p 001e7000 08:05 1837188                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f971ed19000-7f971ed1c000 rw-p 001ea000 08:05 1837188                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f971ed1c000-7f971ed20000 rw-p 00000000 00:00 0
7f971ed20000-7f971ed21000 r--p 00000000 08:05 1837189                    /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f971ed21000-7f971ed23000 r-xp 00001000 08:05 1837189                    /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f971ed23000-7f971ed24000 r--p 00003000 08:05 1837189                    /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f971ed24000-7f971ed25000 r--p 00003000 08:05 1837189                    /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f971ed25000-7f971ed26000 rw-p 00004000 08:05 1837189                    /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f971ed26000-7f971ed34000 r--p 00000000 08:05 1841972                    /usr/lib/x86_64-linux-gnu/libtinfo.so.6.2
7f971ed34000-7f971ed43000 r-xp 0000e000 08:05 1841972                    /usr/lib/x86_64-linux-gnu/libtinfo.so.6.2
7f971ed43000-7f971ed51000 r--p 0001d000 08:05 1841972                    /usr/lib/x86_64-linux-gnu/libtinfo.so.6.2
7f971ed51000-7f971ed55000 r--p 0002a000 08:05 1841972                    /usr/lib/x86_64-linux-gnu/libtinfo.so.6.2
7f971ed55000-7f971ed56000 rw-p 0002e000 08:05 1841972                    /usr/lib/x86_64-linux-gnu/libtinfo.so.6.2
7f971ed56000-7f971ed58000 rw-p 00000000 00:00 0
7f971ed64000-7f971ed6b000 r--s 00000000 08:05 2498817                    /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7f971ed6b000-7f971ed6c000 r--p 00000000 08:05 1837183                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f971ed6c000-7f971ed8f000 r-xp 00001000 08:05 1837183                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f971ed8f000-7f971ed97000 r--p 00024000 08:05 1837183                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f971ed98000-7f971ed99000 r--p 0002c000 08:05 1837183                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f971ed99000-7f971ed9a000 rw-p 0002d000 08:05 1837183                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f971ed9a000-7f971ed9b000 rw-p 00000000 00:00 0
7fff0c34e000-7fff0c36f000 rw-p 00000000 00:00 0                          [stack]
7fff0c395000-7fff0c398000 r--p 00000000 00:00 0                          [vvar]
7fff0c398000-7fff0c399000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

  

//ToDo增加一個案例,分析記憶體和優化