2012-04-11 17 views
1

スペースを節約するためにLinux上で実行可能なページを共有することは可能ですか?私は、異なるプロセス間でメモリを共有するために使用できる共有メモリAPIがあることを知っていますが、それはそのために使用されるとは思われません。Linuxで実行可能なメモリページを共有しますか?

基本的には、一般的に使用されている共有ライブラリをロードできる共有メモリ領域が必要です。私はすべての共有ライブラリイメージをすべての単一のプロセス(無駄に思える)にロードするのではなく、プリロードされた(読み込み専用の)イメージとリンクするために動的リンカーを取得したい。

これはLinuxカーネルで可能ですか?ダーウィンカーネルはcommpagesと呼ばれるMach VMの機能を使用してこれを実装します(dyld共有キャッシュはそこに格納されます)。このコマンドは、すべてのプロセスにアクセス可能であり、共有されています。

明確にするために、私は共有オブジェクト(ライブラリ)が何であるかを知っています。現在、Linux上でダイナミックリンカが行うことは、必要なライブラリをすべてプログラムのアドレス空間にロードすることです。つまり、libc(たとえば)とリンクする各アプリケーションは、アドレス空間のどこかにlibcのイメージを持ちます。ダーウィンでは、この問題は、のlibcの実行可能な(および他の読み取り専用の)セクションを共有メモリページのセットにすることによって取り除くことができます。共有イメージの書き込み可能なセクションは依然として分離されています。

編集:私は、ELF形式では共有ライブラリのDATAセグメントとTEXTセグメントを分離できないことを知っています。私はELFを使用していません。私は別のバイナリ形式(自分のbinfmtカーネルモジュールと自分のダイナミックリンカを使用しています)を使用しています。私は、Linuxカーネルがコマケーションのような機能をサポートしていれば興味があります。

編集2:これを行うには、カーネルに大きなスラブのメモリを割り当て、実行されるすべてのバイナリにマップするしかありません。バイナリが最初に実行されると、ダイナミックリンカは保護を解除し、目的のデータでそのデータを埋め、保護します。それで何らかの形で、カーネルはメモリセグメントが何かによって変更されていないことを確認しなければならないでしょう。別の

答えて

4

geekosaur氏によると、Linuxはすでにこれを行っています。

アプリケーションの起動時に、ダイナミックリンカ(ld.so)mmap()が共有ライブラリです。 これは、ライブラリごとにmmap()にいくつかの呼び出しを実行します(実行可能セクションの

  • mmap(PROT_READ|PROT_EXEC)(すなわち.textの)データの
  • mmap(PROT_READ|PROT_WRITE)(すなわち.dataセクションや.bssの)

ますstraceを使ってこれをチェックすることができます)。

カーネルは賢明な少しのコードであり、オフセットとiノードで識別される実行可能セクションfdによってわかっている)はすでにマップされています。それは読み取り専用なので、それ以上のメモリを割り当てる必要はありません。

これはまた、複数のアプリケーションから読み取ったmmap()の読み取り専用のファイルがあれば、メモリも1回だけ消費されることを意味します。

+0

クリストフの答えは、通常、リンクと読み込みの議論では光沢があります。共有には、同じコードオブジェクト(ファイル内)を参照し、物理メモリ内の同じページ(コード)にアクセスするという2つの概念があります。カーネルのmmap()関数は後者を理解しており、リンクはそれを実現するのに十分理解しているだけです。同じ静的にリンクされたプログラムを実行する2つのプロセスであっても、物理コードページを共有することができます。 – bootchk

4

Linuxは既にこれを行います。実際には、共有オブジェクトは約/ forです。

+0

共有オブジェクトは、すべてのアプリケーションのアドレス空間に複製されます。 –

+0

これらはすべてのアプリケーションのアドレス空間に*マップされますが、物理的にはメモリ上に一度だけ存在します。 –

+0

ld-linuxのどの部分ですか? –

関連する問題