robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 URL
FreeBSD 兮 malloc
by thinker
2 Columns
關鍵字:
FreeBSD
為啥麼,明明就是個小程式,結果佔 memory 50MB? 這是懷疑真久兮問題,就像下面兮 code 要用 50MB 兮空間,你敢相信? {{{ #include <stdio.h> #include <unistd.h> main() { sleep(10); } }}} 實際上,static link 和 dynamic link 兮版本,大小差真多。 {{{ gcc -o sleep_d sleep.c gcc -o sleep_s -static sleep.c }}} 下面是 static 版本兮執行結果: {{{ thinker@fishman$$ ./sleep_s& ps aux|grep sleep_s [1] 45074 thinker 45074 0.0 0.2 48992 196 p5 S 7:15PM 0:00.02 ./sleep_s thinker 45076 0.0 0.8 50296 968 p5 S+ 7:15PM 0:00.07 grep sleep_s }}} VSZ 是 48992KB,而 RSS 是 196k。 這是 dynamic 版本兮執行結果: {{{ thinker@fishman$$ ./sleep_d& ps aux|grep sleep_d [1] 45633 thinker 45633 0.0 0.4 1244 460 p5 S 7:16PM 0:00.03 ./sleep_d thinker 45635 0.0 0.8 50296 932 p5 R+ 7:16PM 0:00.06 grep sleep_d thinker@fishman$$ }}} VSZ 是 1244KB,而 RSS 是 460KB。 但,static 版本敢真正大這麼多? {{{ thinker@fishman$$ ls -l sleep_[sd] -rwxr-xr-x 1 thinker users 4713 Jan 29 19:15 sleep_d -rwxr-xr-x 1 thinker users 174226 Jan 29 19:15 sleep_s thinker@fishman$$ }}} 174KB V.S. 4.7KB,是差抹少,但是 170KB 會差這多?48MB 比 1.2MB,不免乎我懷疑。 strip 看麼: {{{ thinker@fishman$$ strip sleep_[ds] thinker@fishman$$ ls -l sleep_[sd] -rwxr-xr-x 1 thinker users 3012 Jan 29 19:21 sleep_d -rwxr-xr-x 1 thinker users 139208 Jan 29 19:21 sleep_s thinker@fishman$$ }}} 也是差無多。 == 執行檔 header == 用 readelf 檢查 static 執行檔兮內容: {{{ thinker@fishman$$ readelf -a sleep_s ELF Header: Magic: 7f 45 4c 46 01 01 01 09 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - $FreeBSD$ ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x8048088 Start of program headers: 52 (bytes into file) Start of section headers: 138688 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 2 Size of section headers: 40 (bytes) Number of section headers: 13 Section header string table index: 12 Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .init PROGBITS 08048074 000074 000011 00 AX 0 0 4 [ 2] .text PROGBITS 08048088 000088 0195b7 00 AX 0 0 4 [ 3] .fini PROGBITS 08061640 019640 00000c 00 AX 0 0 4 [ 4] .rodata PROGBITS 08061660 019660 00385e 00 A 0 0 32 [ 5] .data PROGBITS 08065000 01d000 001cc4 00 WA 0 0 32 [ 6] .eh_frame PROGBITS 08066cc4 01ecc4 000004 00 A 0 0 4 [ 7] .ctors PROGBITS 08066cc8 01ecc8 000008 00 WA 0 0 4 [ 8] .dtors PROGBITS 08066cd0 01ecd0 000008 00 WA 0 0 4 [ 9] .jcr PROGBITS 08066cd8 01ecd8 000004 00 WA 0 0 4 [10] .bss NOBITS 08066ce0 01ece0 003068 00 WA 0 0 32 [11] .comment PROGBITS 00000000 01ece0 003087 00 0 0 1 [12] .shstrtab STRTAB 00000000 021d67 000056 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x08048000 0x08048000 0x1cebe 0x1cebe R E 0x1000 LOAD 0x01d000 0x08065000 0x08065000 0x01cdc 0x04d48 RW 0x1000 Section to Segment mapping: Segment Sections... 00 .init .text .fini .rodata 01 .data .eh_frame .ctors .dtors .jcr .bss There is no dynamic segment in this file. There are no relocations in this file. There are no unwind sections in this file. No version information found in this file. thinker@fishman$$ }}} readelf 顯示,loader 會對執行檔 load 兩個 segement,第一個兮 memory size 是 0x1cebe,第二個是 0x04d48。也就是 138246 bytes 左右 => 138KB。也就是,多出 4XMB 是 heap 和 stack?但是 dynamic 版本沒用這麼多 heap 和 stack?heap 兮配置,應該和 libc 兮記憶體管理有關係,所以我查了 malloc(3) 之後,發現可以在程式結果時,印出配置狀況。 == MALLOC 兮$統計$資料 == {{{ thinker@fishman$$ MALLOC_OPTIONS=P ./sleep_s 2>&1|more ___ Begin malloc statistics ___ Number of CPUs: 1 Number of arenas: 1 Cache slots: 256 Chunk size: 16777216 (2^24) Quantum size: 16 (2^4) Pointer size: 4 Number of bins: 128 Maximum bin size: 2096 Assertions enabled Redzone size: 16 Allocated: 128, space used: 33554432 chunks: nchunks highchunks curchunks 2 2 2 arenas[0] statistics: calls: nmalloc npalloc ncalloc ndalloc nralloc 2 0 0 0 0 region events: nsplit ncoalesce ...... SKIP ....... }}} 哇 33554432 bytes == 33.5MB !!! 怎麼一次就配這麼多? 再看看 dynamic 版本,配比較少 heap? {{{ thinker@fishman$$ MALLOC_OPTIONS=P ./sleep_d 2>&1|more thinker@fishman$$ }}} 咧!! 無配?? 無可能,敢是因為沒使用到 heap,所以無配?但是,為什麼 static 版本就先配好?敢說 static 和 dynamic 兮 initial code 作沒無同? 來試看昧: {{{ #include <stdio.h> #include <unistd.h> main() { char *p; p = (char *)malloc(16); sleep(10); } }}} 執行 malloc 之後,應該都會配置。 compile: {{{ thinker@fishman$$ gcc -o sleep_s -static sleep.c thinker@fishman$$ gcc -o sleep_d sleep.c thinker@fishman$$ ls -l sleep_[sd] -rwxr-xr-x 1 thinker users 4808 Jan 29 19:44 sleep_d -rwxr-xr-x 1 thinker users 174226 Jan 29 19:44 sleep_s thinker@fishman$$ }}} 看起來,大小差無多。 {{{ thinker@fishman$$ ./sleep_d& ps aux|grep sleep_d [1] 60455 thinker 60455 0.0 0.5 50100 632 p5 S 7:47PM 0:00.04 ./sleep_d thinker 60457 0.0 0.8 50296 964 p5 R+ 7:47PM 0:00.08 grep sleep_d thinker@fishman$$ thinker@fishman$$ ./sleep_s& ps aux|grep sleep_s [1] 61199 thinker 61199 0.0 0.2 48992 196 p5 S 7:48PM 0:00.02 ./sleep_s thinker 61201 0.0 0.8 50296 964 p5 S+ 7:48PM 0:00.06 grep sleep_s thinker@fishman$$ }}} 哈!大小差不多。所以,應該是兩個版本兮 initial code 兮處理方法無同。 來看看 malloc 兮配置: {{{ thinker@fishman$$ MALLOC_OPTIONS=P ./sleep_d 2>&1|more ___ Begin malloc statistics ___ Number of CPUs: 1 Number of arenas: 1 Cache slots: 256 Chunk size: 16777216 (2^24) Quantum size: 16 (2^4) Pointer size: 4 Number of bins: 128 Maximum bin size: 2096 Assertions enabled Redzone size: 16 Allocated: 64, space used: 33554432 chunks: nchunks highchunks curchunks 2 2 2 arenas[0] statistics: calls: nmalloc npalloc ncalloc ndalloc nralloc 1 0 0 0 0 region events: nsplit ncoalesce ...... SKIP ...... }}} 嘿! malloc 有進行記憶體兮配置。 == 結論 == malloc 一開始就會配 3xMB 左右兮空間,看起真浪費。但是,另一方面,配置之後若是無用著,只是在 page table 佔一點空間而己,並抹實際配得 memory,連 swap 也抹用著。這是為啥麼,咱常常會懷疑,明明是 hello world 兮小程式,卻用這麼多兮空間。如果你注意看 bash: {{{ thinker@fishman$$ ps aux|grep bash root 462 0.0 0.0 3180 0 v0 IW - 0:00.00 -bash (bash) thinker 45922 0.0 0.3 3156 372 p1 Is 3:02PM 0:00.56 bash thinker 64172 0.0 0.3 3152 364 p2 Is 3:29PM 0:00.27 bash thinker 65191 0.0 0.8 50296 964 p5 S+ 7:53PM 0:00.06 grep bash thinker@fishman$$ }}} 皆比咱兮 hello world 小,這是啥情形??!! 其實就是 heap 兮問題。這類程式,應該在 heap 兮使用上,有特別兮設計。甚至是無用 $FreeBSD$ 兮 malloc,而是用自己兮版本。下一次,在算記憶體用量兮時,應該也將配了,卻無佇用兮空間可慮入去。 == $FreeBSD$ 版本 == {{{ thinker@fishman$$ uname -a $FreeBSD$ fishman.branda.to 7.0-CURRENT $FreeBSD$ 7.0-CURRENT #0: Sat Jan 28 18:12:49 CST 2006 thinker@fishman.branda.to:/usr/obj/usr/src/sys/GENERIC i386 thinker@fishman$$ }}}
最後更新時間: 2006-01-29 21:16:37 CST |
引用
查詢:
COMMENTS: