天天看點

tcmalloc庫使用測試

利用LD_PRELOAD來加載tcmalloc庫

在編譯時顯式連結tcmalloc庫

試驗

試驗1:不連結tcmalloc

試驗2:僅顯式連結tcmalloc

試驗3:顯式連結libc和tcmalloc,libc在前

試驗4:顯式連結libc和tcmalloc,tcmalloc在前

結論

利用LD_PRELOAD來加載tcmalloc庫

那麼使用者調用malloc肯定是走到tcmalloc中;

在編譯時顯式連結tcmalloc庫

如何保證在運作時,malloc符号是綁定到tcmalloc内的?

僅通過動态庫加載順序?還是有其它機制?

試驗

x86_64平台。

寫一個hello小程式,調用一次malloc函數。

利用如下指令來檢視依賴庫及malloc符号的綁定結果:

objdump -x a.out |grep NEEDED

LD_DEBUG=bindings ./a.out

試驗1:不連結tcmalloc

[[email protected] hello]$ objdump a.out -x |grep NEEDED

NEEDED libc.so.6

[[email protected] hello]$ LD_DEBUG=bindings ./a.out

5363: initialize program: ./a.out

5363:

5363:

5363: transferring control: ./a.out

5363:

5363: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `malloc' [GLIBC_2.2.5]

5363: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]

5363:

5363: calling fini: ./a.out [0]

試驗2:僅顯式連結tcmalloc

[[email protected] hello]$ gcc hello.c -ltcmalloc

[[email protected] hello]$ objdump a.out -x |grep NEEDED

NEEDED libtcmalloc.so.4

NEEDED libc.so.6

[[email protected] hello]$ LD_DEBUG=bindings ./a.out

5414: initialize program: ./a.out

5414:

5414:

5414: transferring control: ./a.out

5414:

5414: binding file ./a.out [0] to /lib64/libtcmalloc.so.4 [0]: normal symbol `malloc'

5414: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]

5414:

5414: calling fini: ./a.out [0]

試驗3:顯式連結libc和tcmalloc,libc在前

[[email protected] hello]$ gcc hello.c -lc -ltcmalloc

[[email protected] hello]$ objdump a.out -x |grep NEEDED

NEEDED libc.so.6

NEEDED libtcmalloc.so.4

[[email protected] hello]$ LD_DEBUG=bindings ./a.out

5463: initialize program: ./a.out

5463:

5463:

5463: transferring control: ./a.out

5463:

5463: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `malloc' [GLIBC_2.2.5]

5463: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]

5463:

5463: calling fini: ./a.out [0]

試驗4:顯式連結libc和tcmalloc,tcmalloc在前

[[email protected] hello]$ gcc hello.c -ltcmalloc -lc

[[email protected] hello]$ objdump a.out -x |grep NEEDED

NEEDED libtcmalloc.so.4

NEEDED libc.so.6

[[email protected] hello]$ LD_DEBUG=bindings ./a.out

5501: initialize program: ./a.out

5501:

5501:

5501: transferring control: ./a.out

5501:

5501: binding file ./a.out [0] to /lib64/libtcmalloc.so.4 [0]: normal symbol `malloc'

5501: binding file ./a.out [0] to /lib64/libc.so.6 [0]: normal symbol `memset' [GLIBC_2.2.5]

5501:

5501: calling fini: ./a.out [0]

結論

經過上述測試驗證(也作了libstdc++ / new函數的測試),

當顯式連結libtcmalloc時,程序的malloc/new最終能不能調到tcmalloc中,取決于程序對動态庫的依賴順序。

如果編譯軟體時,既顯式連結libc(或libstdc++),又顯式連結libtcmalloc,那麼必須保證先連結tcmalloc再連結libc(或libstdc++),否則,malloc/new函數還是被綁定到原生的libc(或libstdc++)中。

延伸:

程序加載多個依賴庫時,可以選擇廣度優先周遊加載,也可以選擇深度優先周遊加載,不同的加載政策,會導緻某些動态庫的加載順序發生變化,如果多個動态庫中含有相同的動态符号,那麼會産生不同的符号綁定結果。但對于tcmalloc來說,隻要不顯示連結libc(或libstdc++),一般就沒什麼問題,因為不管廣度優先還是深度優先,tcmalloc必然在libc(libstdc++)之前先被加載。

————————————————

版權聲明:本文為CSDN部落客「bobbypollo」的原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/bobbypollo/article/details/79906985

上一篇: PageHeap
下一篇: TCMalloc原理

繼續閱讀