2

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

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

これはLinuxカーネルで可能ですか?Darwinカーネルは、commpagesと呼ばれるMach VMの機能を使用してこれを実装します dyld共有キャッシュはそこに保存されます)。Commpageは、すべてのプロセスにアクセスして共有できます。

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

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

編集2:これを行うことを考えることができる唯一の方法は、カーネルにメモリの大きなスラブを割り当て、実行されるすべてのバイナリにそれをマップすることです。バイナリが初めて実行されると、ダイナミックリンカはそのバイナリの保護を解除し、目的のデータを入力して保護することができます。次に、どういうわけか、カーネルは、メモリセグメントが他の何かによって変更されていないことを確認する必要があります。これは、大規模なセキュリティホールを開くためです。別

4

2 に答える 2

6

geekosaurが言ったように、Linuxはすでにこれを行っています。

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

  • mmap(PROT_READ|PROT_EXEC)実行可能セクション(つまり.text)の場合
  • mmap(PROT_READ|PROT_WRITE)データ(つまり、.dataおよび.bss)

(これは、を使用して自分で確認できますstrace。)

カーネルは巧妙なコードであり、offsetとiノード(fdで知られている)で識別される実行可能セクションがすでにマップされていることを認識しています。読み取り専用であるため、より多くのメモリを割り当てる意味はありません。

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

于 2012-04-11T19:48:08.360 に答える
4

Linuxはすでにこれを行っています。実際、それが共有オブジェクトの目的です。

于 2012-04-11T00:55:40.160 に答える