メモリ情報
D言語でプロセス・システムのメモリ使用量をとりたいときどうするんだ、みたいな話があって、自分だとmallinfo(3)とかで
import std.stdio; extern(C) { struct mallinfo_ { int arena; /* Non-mmapped space allocated (bytes) */ int ordblks; /* Number of free chunks */ int smblks; /* Number of free fastbin blocks */ int hblks; /* Number of mmapped regions */ int hblkhd; /* Space allocated in mmapped regions (bytes) */ int usmblks; /* Maximum total allocated space (bytes) */ int fsmblks; /* Space in freed fastbin blocks (bytes) */ int uordblks; /* Total allocated space (bytes) */ int fordblks; /* Total free space (bytes) */ int keepcost; /* Top-most, releasable space (bytes) */ } mallinfo_ mallinfo(); } void main() { auto mi = mallinfo(); writefln("Total non-mmapped bytes (arena): %d", mi.arena); ... }
みたいなかんじでutilを作ってやったりしてました。
https://dlang.org/spec/interfaceToC.html のとおり extern(C)
内に書いたやつはDコンパイラがいいかんじにmangleとか呼び出し規約とかみてくれるのでわりと意識せずに書けます。
mallinfo(3)はglibcにあるので別共有ライブラリにリンクする必要もないし楽です。
% readelf -s /lib64/libc.so.6| grep mallinfo 1199: 0000000000081b60 258 FUNC GLOBAL DEFAULT 12 __libc_mallinfo@@GLIBC_2.2.5 1446: 0000000000081b60 258 FUNC WEAK DEFAULT 12 mallinfo@@GLIBC_2.2.5 1063: 000000000007bf90 278 FUNC LOCAL DEFAULT 12 int_mallinfo 3830: 0000000000081b60 258 FUNC LOCAL DEFAULT 12 __mallinfo 5867: 0000000000081b60 258 FUNC GLOBAL DEFAULT 12 __libc_mallinfo 7228: 0000000000081b60 258 FUNC WEAK DEFAULT 12 mallinfo
別プロセスのが欲しいときとかだと /proc/<PID>/statm
をファイルとして開いたりというかんじでした。
まあこういうのやはりdubにパッケージがあって resusage というのを使えば良さそうです。 ある程度ポータブルに動くのでこういうの使ったほうがいいですね。
Linuxだとシステム全体のメモリ使用統計はsysinfo(2)使ってて、プロセス単位だと /proc/<PID>/stat
をパースしてます。メモリだけならstatmでいいんじゃないの?と思うんですがCPU側とかの統計もとっててstatを共通のインターフェースとして使ってるんですよね。
リンクの話
D言語、というかdmdの吐くバイナリのリンク処理ってどうなってるの、みたいな。
まず環境
% cat /etc/{redhat,centos}-release CentOS Linux release 7.1.1503 (Core) CentOS Linux release 7.1.1503 (Core) % uname -mrv 3.10.0-229.14.1.el7.x86_64 #1 SMP Tue Sep 15 15:05:51 UTC 2015 x86_64
わりと一般的ですね?
dmdにおいて、リンク処理はccをたたいて実現しています。
% dmd -v hello.d| tail -1 cc hello.o -o hello -m64 -L/home/hiroki.noda/dlang/dmd-2.071.1/linux/bin64/../lib64 -Xlinker --export-dynamic -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl
ccは手元の環境だとGCCです。リンク処理はGNU ldを使ってます。GCCが内部でldを呼ぶときはデフォルトでlibc.soとかもろもろを動的リンクするようになっています。ここではさらに明示的にlibpthread.soだとかlibm.soだとかがされてますね。
% cc --version cc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9) % ld --version GNU ld version 2.23.52.0.1-30.el7_1.2 20130226
lddで調べてみるともろもろ動的リンクされてます。
% ldd hello linux-vdso.so.1 => (0x00007ffc4c908000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f2e461e5000) libm.so.6 => /lib64/libm.so.6 (0x00007f2e45ee2000) librt.so.1 => /lib64/librt.so.1 (0x00007f2e45cda000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f2e45ad6000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f2e458bf000) libc.so.6 => /lib64/libc.so.6 (0x00007f2e454fe000) /lib64/ld-linux-x86-64.so.2 (0x00007f2e46411000)