Rust では今までmemory allocatorとしてjemallocが使われてきましたが、先日リリースされた1.32 ではデフォルトではjemallocでなくてシステム標準のものが使用されるように変更されました。
jemalloc-is-removed-by-default
これによって実行ファイルのサイズがその分小さくなるはずなので、それを確認してみました。
確認方法
x86_64のRustの1.31.1 と 1.32.0で以下のことを行い、それそれのバイナリサイズを見てみます。
cargo new hello
cd hello/
cargo build --release
cd target/release/
cp hello hello_g
strip hello
1.31.1
$ rustc --version
rustc 1.31.1 (b6c32da9b 2018-12-18)
$ ls -lh hello hello_g
-rwxr-xr-x 2 koba dev 427K 1月 19 16:40 hello
-rwxr-xr-x 1 koba dev 3.9M 1月 19 16:39 hello_g
1.32.0
$ rustc --version
rustc 1.32.0 (9fda7c223 2019-01-16)
$ ls -lh hello hello_g
-rwxr-xr-x 2 koba koba 191K 1月 19 16:35 hello
-rwxr-xr-x 1 koba koba 2.3M 1月 19 16:35 hello_g
stripした実行ファイルで236KB小さくなっていることがわかりました。
malloc のシンボルを調べた
malloc
とつくシンボルをgrepしてみました。
1.31.1
$ nm hello_g |grep malloc
000000000002fb20 t arena_bin_malloc_hard
000000000003c220 t config_malloc_conf_ctl
000000000003c640 t config_xmalloc_ctl
00000000000230c0 t je_a0malloc
00000000000305f0 t je_arena_malloc_hard
00000000000302e0 t je_arena_malloc_large
00000000000413d0 t je_huge_malloc
000000000002c1d0 T je_jemalloc_postfork_child
000000000002c080 T je_jemalloc_postfork_parent
000000000002bdf0 T je_jemalloc_prefork
000000000002ba80 t jemalloc_constructor
000000000004c000 t je_malloc_cprintf
0000000000042a50 t je_malloc_mutex_boot
0000000000042960 t je_malloc_mutex_init
00000000000429e0 t je_malloc_mutex_postfork_child
00000000000429d0 t je_malloc_mutex_postfork_parent
00000000000429c0 t je_malloc_mutex_prefork
000000000004c0d0 t je_malloc_printf
000000000004bf70 t je_malloc_snprintf
000000000004a530 t je_malloc_strtoumax
000000000004a370 t je_malloc_tsd_boot0
000000000004a410 t je_malloc_tsd_boot1
000000000004a720 T je_malloc_vsnprintf
000000000004a480 t je_malloc_write
000000000026a2da B je_opt_xmalloc
0000000000023f50 T malloc
000000000026a340 V malloc_conf
000000000026a048 D __malloc_hook
000000000002c320 t malloc_init_hard_a0_locked
000000000026a348 b malloc_initializer
000000000026a060 d malloc_init_state
000000000026b1a0 B malloc_message
000000000026a038 d malloc_slow
000000000026a350 b malloc_slow_flags
000000000002b7a0 T malloc_stats_print
000000000002b850 T malloc_usable_size
0000000000027710 T mallocx
000000000003cb40 t opt_xmalloc_ctl
000000000003f4a0 t stats_arenas_i_bins_j_nmalloc_ctl
000000000003fe10 t stats_arenas_i_hchunks_j_nmalloc_ctl
000000000003f270 t stats_arenas_i_huge_nmalloc_ctl
000000000003efb0 t stats_arenas_i_large_nmalloc_ctl
000000000003faf0 t stats_arenas_i_lruns_j_nmalloc_ctl
000000000003ecf0 t stats_arenas_i_small_nmalloc_ctl
jemallocがリンクされています。
1.32.0
$ nm hello_g |grep malloc
U malloc@@GLIBC_2.2.5
malloc はglibc のものがダイナミックリンクされるようになっています。
関連
rustをインストールしてhello world をARM用にクロスコンパイルするまでの手順
以前この記事の中で、バイナリサイズが大きいなと書いたらコメントで
「ヒープアロケータを、スタティックリンクされたjemallocから、ダイナミックリンクのシステムアロケータ(libcのmalloc)に変更する」
という方法を教わりました。Rust 1.32ではデフォルトでそのような動作になったということです。