GNU/Linux >> Linux の 問題 >  >> Linux

メモリ マップド ページと匿名ページとは何ですか?

正しい用語は、メモリ マップされた ファイル です。 および匿名のマッピング。メモリ マッピングについて言及する場合、通常は mmap(2) について言及します。 mmap の使用には 2 つのカテゴリがあります。 1 つのカテゴリは、SHARED と PRIVATE のマッピングです。もう 1 つのカテゴリは、FILE と ANONYMOUS のマッピングです。混ぜ合わせると、次の 4 つの組み合わせが得られます:

<オール>
  • プライベート ファイル マッピング
  • 共有ファイルのマッピング
  • プライベート匿名マッピング
  • 共有匿名マッピング
  • ファイル マッピングは、N 個のバイトがメモリにマップされるディスク上のファイルを指定します。関数 mmap(2) は、4 番目の引数として、メモリにマップされるファイルへのファイル記述子を取ります。 5 番目の引数は、オフセットとして読み込まれるバイト数です。 mmap を使用してメモリ マップド ファイルを作成する一般的なプロセスは次のとおりです

    <オール>
  • ファイル記述子を取得するためにファイルを open(2) します。
  • fstat(2) ファイル記述子のデータ構造からサイズを取得するファイル
  • mmap(2) open(2) から返されたファイル記述子を使用するファイル
  • close(2) ファイル記述子
  • メモリ マップされたファイルに対して何でも行います。
  • ファイルが PRIVATE としてマップされている場合、加えられた変更は基になるファイルにコミットされません。これは、ファイルのプライベートなメモリ内コピーです。ファイルが SHARED にマップされると、加えられた変更はカーネルによって基になるファイルに自動的にコミットされます。共有としてマップされたファイルは、いわゆるメモリ マップド I/O および IPC に使用できます。ファイルの永続性が必要な場合は、共有メモリ セグメントの代わりにメモリ マップド ファイルを IPC に使用します

    strace(1) を使用してプロセスの初期化を監視すると、mmap(2) をプライベート ファイル マッピングとして使用して、ファイルのさまざまなセクションがマップされていることがわかります。同じことがシステム ライブラリにも当てはまります。

    strace(1) からの出力の例。mmap(2) を使用してライブラリでプロセスにマップしています。

    open("/etc/ld.so.cache", O_RDONLY)      = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=42238, ...}) = 0
    mmap(NULL, 42238, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff7ca71e000
    close(3)                                = 0
    open("/lib64/libc.so.6", O_RDONLY)      = 3
    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\356\341n8\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=1926760, ...}) = 0
    mmap(0x386ee00000, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x386ee00000
    

    匿名マッピングは、ファイルによってサポートされません。具体的に言うと、mmap(2) の 3 番目の引数として MAP_ANONYMOUS フラグが使用されている場合、mmap(2) の 4 番目 (ファイル記述子) と 5 番目 (オフセット) の引数は使用されません。 MAP_ANONYMOUS フラグを使用する代わりに、ファイルとして /dev/zero を使用することもできます。

    「匿名」という言葉は、あたかもファイルが匿名でマッピングされているかのように聞こえるという点で、私には不適切な選択です。代わりに、匿名のファイルです。ファイルが指定されていません。

    ユーザーランドプログラミングでは、プライベート匿名マッピングの使用はほとんどありません。アプリケーションがメモリの領域を共有できるように、共有匿名マッピングを使用できますが、代わりに SYSV または POSIX 共有メモリを使用しない理由はわかりません。

    Anonymous マッピングを使用してマップされたメモリはゼロで埋められることが保証されているため、メモリのゼロで埋められた領域を期待/必要とする一部のアプリケーションでは、malloc(2) + memset(2) の代わりにこの方法で mmap(2) を使用すると便利です。 ) コンボ。


    私が理解しているように、匿名ページには名前付きのファイルシステムソースがないため、名前が付けられていますが、マップされたページは具体的なファイルのマッピングです。たとえば、任意のユーザー空間プロセスで単純な malloc 操作を使用して匿名ページを取得できます...

    カーネル構造について:明らかに 構造ページ です ですが、anonymos ページの場合は struct anon_vma があります ページに座っている->マッピング、およびマップされたページの場合- struct address_space 、具体的な inode に接続されています。


    Linux
    1. シンボリック リンク (ソフト リンク) とは何か、および Linux でそれらを作成する方法

    2. Linux のスパース ファイルとは

    3. .pid ファイルとは何ですか? また、何が含まれていますか?

    1. NFSとは何ですか?Linuxにインストールする方法

    2. どのような追加のサムナイラーが利用可能であり、それらをインストールする方法は?

    3. vdso と vsyscall とは何ですか?

    1. Linux の /dev/zero および /dev/null ファイルとは

    2. libtool の .la ファイルは何のためのものですか?

    3. ファイルへの書き込みとマップされたメモリへの書き込みの違いは何ですか?