2014年5月21日水曜日

Androidのスタックサイズ

昔私がアホだった頃、DOSで動くあるプログラムをCで作ったとき、
実行時にエラーが出て動作してくれませんでした。
何のことはない、ローカルスコープで巨大な配列を確保したために
スタックがなくなったというオチです。
C言語の入門書なんかを見ると、大きな配列はmalloc()を使えみたいなことが
理由もなく書いてあるものを見たことがありましたが、今でもそうなんでしょうかね?
まったく本質的ではありません。

当時すでにアセンブラの知識があり、
スタックがどういうものかも理解していましたがCを使い始めたところで、
高級言語が如何にして実行可能プログラムに落とし込まれているかを
意識するところまで達しておりませんでした。
かしこくなった今ではコンパイル後のコードを想像しながらCを使うようになり、
ローカル変数の宣言のならべ順さえも気になって仕方ありません。
これって強迫性障害なのか?

さて、スタックが足りなくならないようにヒープを使うというのは
理屈としてはあっていても思想としては間違っています。
まあ別にどうでもいい話ですが。
ではスタックは増やせるのかというと実は簡単に増やせて、
大昔はcl(MicrosoftのCコンパイラ)に
"/F <スタックサイズ(単位:B)>"オプションをつけて対応したことがあります。
このときの経験からスタックサイズは
コンパイラが決定していると理解し納得したものです。

ところがLinuxでは各プログラムのスタックサイズは実行環境(シェル?)が決定しており、
$ ulimit -s <スタックサイズ(単位:KB)>
で変更可能です。
ただ、もしかしたらgccのオプションに何かあるかも知れません。

ではAndroidアプリケーションではどうなっているかというと、
こちらも実行環境依存です。
dalvik仮想マシンの起動時にオプションで指定できます。
コマンドラインで
# dalvikvm --help
を実行すると出力されるメッセージの中に、
-XssN  (stack size, >= 1KB, <= 256KB)
のような記述があり、
"-Xss"オプションでスタックサイズが指定できることがわかります。
実はこれJavaと一緒なんですね。

それならAndroidアプリケーションは好きなサイズのスタックを
コマンドラインオプションで設定できるかというと、
通常そういうわけにはいきません。
基本的には常にデフォルト値が使用されます。
Androidフレームワークのソースを見ると、
"dalvik/vm/Thread.h"でkDefaultStackSize定数が定義されており、
これがデフォルトのスタックサイズです。
私がチラッとみたところでは、
バージョン4.2で16KB、2.3で12KBになってますね。
もちろん端末メーカーが変更していないことは保証の限りではなく、
すべてにおいて確かな数値とはいえませんので、念のため。

0 件のコメント:

コメントを投稿