R のデータ構造とメモリ管理
R のメモリプロファイリングをしたかったんですが、表示される結果の意味が理解できなかったので、R のデータ構造とメモリ管理について調べてまとめてみました。
事の発端
Unix において、R のメモリ関連の関数には gc, gcinfo, Rprof, Rprofmem, tracemem, memory.profile, object.size あたりがあります。
例えば gc を実行すると次のような結果が得られます。
> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 180515 9.7 407500 21.8 350000 18.7
Vcells 287939 2.2 905753 7.0 877008 6.7
この結果について、gc のドキュメントには次のように書いてあります。
‘gc’ returns a matrix with rows ‘”Ncells”’ (cons cells),
usually 28 bytes each on 32-bit systems and 56 bytes on 64-bit
systems, and ‘”Vcells”’ (vector cells, 8 bytes each), and
columns ‘”used”’ and ‘”gc trigger”’, each also interpreted in
megabytes (rounded up to the next 0.1Mb).
Writing R Extensions には次のように書いてあります。
Looking at the results of gc() shows a division of memory into Vcells used
to store the contents of vectors and Ncells used to store everything else, including all the
administrative overhead for vectors such as type and length information. In fact the vector
contents are divided into two pools. Memory for small vectors (by default 128 bytes or
less) is obtained in large chunks and then parcelled out by R; memory for larger vectors is
obtained directly from the operating system.
っで、結局 gc の結果はどういう情報なんですか?って感じですよね。used って、メモリ使用量なの?でも 1024 * 1024 で割っても Mb の値と一致しない。他のメモリ関連の関数も「?」な説明が多いです。
というわけで、これは「R のメモリ使用量を知りたいのにデータ構造もメモリ管理の仕方も理解してないとかあり得ないよね」というメッセージだと思って調べることにしました。
Tokyo.R とかで発表すると冷たい目で見られそうなのでひっそりとスライドを公開することにしました。
同じような悩みを抱えた方の理解の助けになれば幸いです。
R のソースコードの読み方もだいぶわかってきたんで、そのうちまとめたいですね。