■
昨日の話は、一日考えて、Cプログラマに若干の負担を負わせないとやっぱり無理なのでは?と、いう結論に。
- 型情報生成ツールを使って型情報を生成すること
- メモリアロケート時に、その型情報を渡すこと
- スタックとローカル変数辿れるように、DWARF2デバッグ情報を残すこと
- intとポインタをごっちゃにしない
いや、でも、許容範囲だと思うんだけど…
まあいいか。気が向いたらやってみる…って、最近、気が向いたらキューを溜めすぎだよな。(いや、気が向いたらキューは溜まらないよ。すぐオーバーフローする。)
それはいいとして、連続するメモリ領域について考える。
オブジェクトがヒープにいるのかを判定するにするには、ヒープ領域が分断されてるよりも、ひとかたまりになっていたほうが良い。そうすれば、一回の判定で、ヒープのオブジェクトなのかどうかが判定できる。
bool is_heap( void *ptr ) { if ( ptr >= heap_begin && ptr < heap_end ) { return true; } return false; }
だが、しかし、ここで問題がある。ヒープ領域をひとつにしたい、ということは、ヒープ領域を分断できない、ということである。。
もし、なんかのライブラリがヒープ領域を使ってた場合、GCの領域を拡張できないかもしれない
GCがヒープ確保→なんかのライブラリがmalloc→GCの領域を拡張
このとき、GCの領域を拡張するのが不可能になるかもしれない。
この問題で、一番手っ取り早い解決方法は、最初に超余裕を持って領域を確保しておく方法だ。
/* 512M !! */ gc_heap = malloc( 512*1024*1024 );
仮想メモリがちゃんとしてあるOSだったら、このぐらいやっちゃっても、実際に書き込まれるまでは、メモリ割り当ては起こらない。必要なときに、必要なだけOSがメモリを割り当ててくれるわけだ。OSは偉い。
でも、この方法はもうちょっと改良したい部分がある。無駄なスワップが起こるという部分だ。
たとえば、一時的に、300MBぐらいメモリを使って、そのあとGCが動いて、使ってるメモリが15MBぐらいになったとする。
このとき、使わない285MBは、必要の無い領域になる、が、しかし、この領域には一旦書き込んでしまってるので、ページが割り当てられているわけだ。そうなると、他のプロセスがメモリを必要としたときに、この領域がスワップアウトしてしまう。
つまり、無駄なスワップが発生してしまうわけだ。PC使ってる時のストレスの80%ぐらいはスワップが原因(多分)なので、無駄なスワップが発生するのは心苦しい。
けど、まあ、なんか方法があるだろう、と思って、適当に調べてみた。(ここまでが前フリ)
まず、Windowsの場合、MEM_RESERVEとかいうのがあって、メモリは割り当てないけど、アドレス領域は空けとく、とかいうのができるっぽい。
http://www.microsoft.com/japan/developer/library/jpwinpf/_win32_virtualallocex.htm
最初にメモリを割り当てるかわりにRESERVEしておいて、ちょびちょびコミットしたり解放したりしていけば良い感じ。
んで、Linuxの場合。ちょっと汚いけど、mremapを使えばできるような。
一回領域を小さくしてやれば、ページの後ろのほうは、未使用領域にできるはず。多分。
#include <sys/mman.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main( int argc, char **argv ) { int sz = atoi( argv[1] ); int i; char *p; p = mmap( 0, sz*1024*1024, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0 ); for ( i=0; i<sz*1024*1024/4096; i++ ) { memset( p+4096*i, 0xf, 4096 ); } mremap( p, sz*1024*1024, 4096, 0 ); mremap( p, 4096, sz*1024*1024, 0 ); sleep( 30000 ); }
こういう感じ。マルチスレッドだとアレだが。
あと、BSDでは、madviseというので、MADV_FREEというのを使えば、できる…ように見えたんだけど、手元のMacではなんかよくわからんかった。使い方が間違ってたのかな…
いや、だからなんだ、という話ではあるんだけど。まあ、知ってれば、そのうち役に立つこともあるかもしれない。