共有ライブラリの動作の不思議 [日常のあれやこれや]
たまたまプロットライブラリでさらにLAPACKライブラリを呼ぶのは良くないだろう、それはLAPACKのほんのわずかな機能を使うために全体をロードする必要が出てしまうから、と思った。
けど、ふと、疑問が湧いた。共有ライブラリってアンロードされることってあるの?
unixでは昔はライブラリはスタティックにアプリケーションにリンクされていた。アプリケーションが起動されると仮想空間のTEXT領域に実行コードや変更されないデータがロードされ、同じ領域にライブラリもロードされた。
複数のアプリケーションが起動されたとき、それらが使うライブラリは別々の仮想空間にロードされるけど、同じライブラリが使われていたとしても別々にロードされる。極端な例としてCのランタイムはunixでは普通、あらゆるアプリケーションが使うけど、この方式ではアプリケーションの数だけ同じランタイムライブラリがメモリの上にあることになる。
これはすごく無駄だ、ということで共有ライブラリというのが作られた。共通で使うライブラリはOSが管理するTEXTメモリ領域にロードされてアプリケーションはシンボルテーブルを経由してライブラリを使う。もともとunixではCの関数呼び出しは実行時にシンボルテーブルを参照するのでオーバーヘッドはどのみち同じになる。
Cのランタイムのようにどのアプリケーションも使いたいものならそれが経済的。でもある特定のアプリケーションしか使わないライブラリがあったとして、それが共有ライブラリとしてロードされたらどうなるのか。
同じようにロードされるけど、それを必要としているアプリケーションが終了した後もライブラリは共有TEXT領域に残ったままになる。なぜならunixは、ある共有ライブラリが使われているかどうかをOSが判断する手段を持っていないから。dbなどのデバッガを使えばわかるけど、これはソフトウェア割り込みを使って実現しているのが普通なのでアプリケーションの実行時に同じメカニズムを使うわけにはいかない。
ということは、一旦ロードされた共有ライブラリはずっとメモリ空間を占有し続けるの?
それとも共有ライブラリ空間もページングの対象になっていて使われなければページアウトされるの?
それとも、例えばアプリケーションを起動するときローダが共有ライブラリのためにシンボルテーブルを更新するはずだけど、そのときに使ってるライブラリはチェックできる。ということはライブラリに対して参照カウンタを持っていてretainCountが0になったらアンロードするとか。
でもその場合、単一の仮想空間の中での作業になるので、ロードアンロードを繰り返すとメモリ空間が穴だらけになる。おお、これでは古いMacOSのHandleの悪夢が甦ってきてしまう。
どうなってんだろ?日本語の情報だけ探していてもなかなか答えにたどり着かない。ま、OSの基本的な機能の実装の問題なので気にする必要はないのだけど、やっぱり気になる。結局滅多に使わないLAPACKみたいなライブラリを使いたいときはスタティックにリンクするべきなのか?
誰か教えて。
けど、ふと、疑問が湧いた。共有ライブラリってアンロードされることってあるの?
unixでは昔はライブラリはスタティックにアプリケーションにリンクされていた。アプリケーションが起動されると仮想空間のTEXT領域に実行コードや変更されないデータがロードされ、同じ領域にライブラリもロードされた。
複数のアプリケーションが起動されたとき、それらが使うライブラリは別々の仮想空間にロードされるけど、同じライブラリが使われていたとしても別々にロードされる。極端な例としてCのランタイムはunixでは普通、あらゆるアプリケーションが使うけど、この方式ではアプリケーションの数だけ同じランタイムライブラリがメモリの上にあることになる。
これはすごく無駄だ、ということで共有ライブラリというのが作られた。共通で使うライブラリはOSが管理するTEXTメモリ領域にロードされてアプリケーションはシンボルテーブルを経由してライブラリを使う。もともとunixではCの関数呼び出しは実行時にシンボルテーブルを参照するのでオーバーヘッドはどのみち同じになる。
Cのランタイムのようにどのアプリケーションも使いたいものならそれが経済的。でもある特定のアプリケーションしか使わないライブラリがあったとして、それが共有ライブラリとしてロードされたらどうなるのか。
同じようにロードされるけど、それを必要としているアプリケーションが終了した後もライブラリは共有TEXT領域に残ったままになる。なぜならunixは、ある共有ライブラリが使われているかどうかをOSが判断する手段を持っていないから。dbなどのデバッガを使えばわかるけど、これはソフトウェア割り込みを使って実現しているのが普通なのでアプリケーションの実行時に同じメカニズムを使うわけにはいかない。
ということは、一旦ロードされた共有ライブラリはずっとメモリ空間を占有し続けるの?
それとも共有ライブラリ空間もページングの対象になっていて使われなければページアウトされるの?
それとも、例えばアプリケーションを起動するときローダが共有ライブラリのためにシンボルテーブルを更新するはずだけど、そのときに使ってるライブラリはチェックできる。ということはライブラリに対して参照カウンタを持っていてretainCountが0になったらアンロードするとか。
でもその場合、単一の仮想空間の中での作業になるので、ロードアンロードを繰り返すとメモリ空間が穴だらけになる。おお、これでは古いMacOSのHandleの悪夢が甦ってきてしまう。
どうなってんだろ?日本語の情報だけ探していてもなかなか答えにたどり着かない。ま、OSの基本的な機能の実装の問題なので気にする必要はないのだけど、やっぱり気になる。結局滅多に使わないLAPACKみたいなライブラリを使いたいときはスタティックにリンクするべきなのか?
誰か教えて。
2008-05-28 23:32
nice!(0)
コメント(0)
トラックバック(0)
コメント 0