2016年09月11日

unix/linuxのメモリ空間の意外と知られていない話

どうも。本職プログラマのアカサコフです。
文章を書く練習のついでに唐突にプログラマらしい事を書いてみます。

タイトルにもあるようにunix/linuxのメモリの話です。
unix/linux上でプログラムがメモリの確保を行ったとき、
例えばC言語で組まれたプログラムでmalloc()か何かでメモリを確保し、
確保したメモリの先頭アドレスを受け取りました。
そのアドレスって”仮想メモリ”のアドレス?、それとも”物理メモリ”のアドレス?
と聞かれて即答できるプログラマって日本に何割位いるんでしょう。

何故こんなことを突然にテーマに書いているかというと
意外とみんな知らないな〜と思う出来事が続いた事と、
若手に説明する際に簡潔に"出来る人風"に説明できるように一旦纏めておこうと思ったからです。
働く気もやる気も技術力も向上心も無い私が知っていたのは本当にたまたまです。

冒頭の問題の正解は"仮想メモリ"のアドレスになります。
OSはプロセス毎に仮想ドレス空間を割り当て、プロセスに提供しているのですね。

OS上で動作するプログラムは基本的に物理メモリのアドレスを触ることも知ることも
(思想的に)出来ないことになっています。

unix/linuxのメモリの世界には以下の4つの世界があります。
・物理メモリ空間
・仮想メモリ空間
・ユーザー空間
・カーネル空間

下2つは聞いたことが無い人もいるかもしれません。

ユーザー空間とはOS上で動作するプロセスが使用する領域であり、
我々が最も良く知っている空間になります。

ではカーネル空間とは何ぞやというと、OSのカーネルやデバイスドライバが使用する領域であり、
システムのコアな部分になります。

そのシステムのコアな部分であるカーネル空間とユーザー空間は完全に別世界となっており、
お互い行き来出来ない事になっています。

その別世界の壁があるおかげでカーネル空間のメモリ空間がユーザー空間上で動くアプリによって壊れる事を防いでいてOSの堅牢さを確保しているわけです。
ですので我々がちょっとアホなプログラムを組んだ位ではOSが落ちないわけです。
まるでその世界の壁は3次元の我々が2次元の世界に行けないが如くですね。

しかし、どんな世界であれ抜け道はあるものです。
このメモリ空間の世界にもきっちり抜け道(行き来出来る関数)が存在します。

あれ、そうすると僕も2次元に行ける抜け道はあるのかもしれない・・・。
僕の想い、ハルゲニアのルイズへ届け!

ということでlinux上でCやJAVAでプログラムを書いてメモリを使用した場合、
使用するメモリ空間というのはユーザー空間、且つ仮想メモリの空間ということになります。

覚えておいて損は無いかもしれないですね。
ただし、以上の事が間違っていても微塵の責任もとりませんので。

私はただの萌え豚の中年なんです。
今期は渡辺曜ちゃん推しです。黒澤ダイヤもレムも良いですね。




以下はどうでもいい話。

カーネル空間のプログラム開発は独自の世界があって面白いです。
stdio.hなどの標準関数はユーザー空間で動くものですので使用しません。

カーネル空間でのみ使用するライブラリ群があります。
例えばprintfに代わるものはprintk、mallocの代わりにkmallocなんかがあったりします。
カーネル空間にも勿論仮想メモリ空間があります。
kmallocで帰ってくるのはカーネル空間の仮想メモリ空間のアドレスです。

デバイスドライバの技術者って今も需要あるみたいですね。。
昔いたブラック会社で月300時間越え勤務が続いたのに年俸制で残業代が1円も支払われなかったし
クライアントが自分の頑張りを認めてくれて単価を上げてくれたのに
中間に居た某社が一切教えてくれなかった(単価を上げてくれなかった)為に、
私の査定に微塵も響かなかった挙句、所属していたブラック会社が突然倒産した事を思い出す。

頑張ったって良いことない。
金に見合う労働をすればいい。いや、いっそ働きたくないでござる。
posted by アカサコフ at 07:10| 日記 | このブログの読者になる | 更新情報をチェックする