11

前提条件

POSIX.1 2008 はおよび関数を指定します。引数にはさまざまな定数が用意されていますが、私の質問を理解しやすくするために、そのうちのいくつかを以下に再掲します。setrlimit()getrlimit()resource

次のリソースが定義されています。

(...)

RLIMIT_DATA

これは、プロセスのデータ セグメントの最大サイズ (バイト単位) です。この制限を超えると、malloc() 関数は失敗し、errno が [ENOMEM] に設定されます。

(...)

RLIMIT_STACK

これは、初期スレッドのスタックの最大サイズ (バイト単位) です。実装によって、この制限を超えてスタックが自動的に拡張されることはありません。この制限を超えると、スレッドに対して SIGSEGV が生成されます。スレッドが SIGSEGV をブロックしている場合、またはプロセスが SIGSEGV を無視またはキャッチしており、代替スタックを使用する準備をしていない場合、SIGSEGV の処理は、生成される前に SIG_DFL に設定されます。

RLIMIT_AS

これは、プロセスで使用可能な合計メモリの最大サイズ (バイト単位) です。この制限を超えると、malloc() および mmap() 関数は失敗し、errno が [ENOMEM] に設定されます。さらに、自動スタック拡張は上記の影響で失敗します。

さらに、POSIX.1 2008では、 データ セグメントを次のように定義しています。

3.125 データセグメント

動的に割り当てられたデータを格納できる、プロセスに関連付けられたメモリ。

RLMIT_DATAリソースは従来、関数を使用してプロセスに割り当てることができるメモリの最大量を示すために使用されていたことを理解していbrk()ます。POSIX.1 の最近の版では、この関数を指定しなくなりました。また、多くのオペレーティング システム (Mac OS X など) は、この関数をシステム コールとしてサポートしていません。代わりにmmap()、POSIX.1 2008 の一部ではないバリアントでエミュレートされます。

質問

リソースのセマンティックと使用について少し混乱していRLIMIT_DATAます。ここに私が持っている具体的な質問があります:

  • この仕様に従って、スタックをデータセグメントの一部にすることはできますか?

  • 標準では、RLIMIT_DATA「この制限を超えると、malloc() 関数は失敗し、errno が [ENOMEM] に設定されます。」これは、割り当てられたメモリmalloc()がデータ セグメントの一部でなければならないということですか?

    Linux では、割り当てられたメモリmmap()はデータ セグメントにカウントされません。brk()またはに割り当てられたメモリのみsbrk()がデータ セグメントの一部です。最近のバージョンの glibc では、malloc()すべてのメモリを .xml で割り当てる実装が使用されていmmap()ます。したがって、 の値はRLIMIT_DATA、 のこの実装で割り当てることができるメモリの量には影響しませんmalloc()

  • これは POSIX.1 2008 に違反していますか?

  • 他のプラットフォームは同様の動作を示しますか?

    標準は次のように述べていRLIMIT_ASます。の障害は にmmap()指定されていないため、 から取得したメモリはデータ セグメントにはカウントされないRLIMIT_DATAと結論付けます。mmap()

  • この仮定は正しいですか?これは の非 POSIX バリアントにのみ適用されますmmap()か?

4

1 に答える 1

2

FreeBSD は、デフォルトの malloc 実装で mmap(2) を使用して実装されている malloc(3) の問題も共有しています。FreeBSD 6 から切り替えが行われた 7 に製品を移植するときに、これに遭遇しました。各プロセスのデフォルトの制限を RLIMIT_DATA=512M から RLIMIT_VMEM=512M に変更しました。つまり、仮想メモリの割り当てを 512MB に制限します。

これが POSIX に違反しているかどうかはわかりません。私の直感では、多くのものが POSIX に違反しており、100% POSIX 準拠のシステムは厳密に確認する C コンパイラと同じくらいまれです。

編集: ええと、FreeBSD の名前 RLIMIT_VMEM が非標準であることがわかりました。POSIX 互換性のために RLIMIT_AS を RLIMIT_VMEM として定義します。

于 2014-05-20T21:48:05.280 に答える