理由がわかりません Box::new
はOption
またはResult
を返しません。
メモリが無制限ではないため、割り当てが失敗する可能性があります。そうしないと、他の何かが発生する可能性があります。そのような場合の動作は何ですか?それについての情報が見つかりません。
より一般的な形式はメモリ不足(OOM)で何をするか?
OOMの取り扱いには多くの困難があります。
最初の問題はそれを検出することです。今日の多くのOSは、デフォルトでスワップスペースを使用します。この場合、スワップスペースの使用を開始するとプロセスが大幅に遅くなるため、OOMの状況に到達する前にプロセスが実際に問題を抱えています。他のOSは、より高いプロセスがより多くのメモリを必要とする場合(OOM killer)、または必要になるまでに使用されないか利用可能になることを期待して(オーバーコミット)、現在よりも多くのメモリを約束する場合、優先度の低いプロセスを強制終了します。等...
2番目の問題は回復です。プロセスレベルでは、回復する唯一の方法は、メモリを解放することです...その間に何も割り当てません。これは思ったほど簡単ではありません。たとえば、パニックと巻き戻しに割り当てメモリが必要ないという保証はありません(たとえば、パニックメッセージを保存する操作を実行すると割り当てられる可能性があります)不注意に)。これが、現在のrustcランタイム デフォルトで中止 on [〜#〜] oom [〜#〜] である理由です。
3番目の問題は言語統合です:メモリ割り当てはどこでもです。 Box
、Vec
、String
などの使用...したがって、パニックルートを避け、代わりにResult
ルートを使用する場合は、この種の失敗を説明するために、ほぼすべてのミューティングメソッドシグネチャを微調整します。これにより、すべてのインターフェイスでバブルが発生します。
最後に、メモリ割り当ての失敗を処理する必要があるドメインでは、メモリ割り当てが not で始まることが許可されていないことがよくあります。たとえば、重要な組み込みソフトウェアでは、すべてのメモリが事前に割り当てられ、割り当てられたもの以上が必要とされないという証明があります。
これは、(1)動的メモリ割り当てが許可され、(2)その障害がプロセス自体によって適切に処理される必要がある非常に少ない状況があることを意味するため、重要です。
そしてこの時点で、これにどれだけの複雑さの予算を費やすべきか、そしてこれがどれほどの複雑さを気にしないプログラムの99%に押し上げるのか疑問に思うだけです。
Liballocの下位レベルの関数のいくつかがOption
sを返さないことに関して、Rust開発者の間で次の通信が見つかりました: PR#142 。
特に次の部分は、その背後にあるいくつかの理由を説明しています。
huonw:
うーん...最下位レベルのライブラリがタスクの失敗を引き起こしてはいけませんか? Optionなどを返す低レベルのライブラリを計画していますか?
alexcrichton:
私は、タスクの失敗をトリガーしたいというのは非常に一般的であることに気づきました。また、必ずしもタスクの失敗ではありませんが、すべてのコンテキストに何らかの形または失敗の概念があることもわかりました。
huonw:
私は、タスクの失敗が呼び出しサイトで回復できないという観点から考えていました。つまり、上位レベルのライブラリは自由に失敗しますが、絶対に低いビルディングブロックは失敗しないようにする必要があります。そうすれば、人々は問題を思いどおりに処理できます(たとえそれがあったとしても)タスクの失敗を手動でトリガーするだけです)。 liballocが最低レベルの割り振りライブラリーになるように設計されていない場合、失敗しても問題ありません。 (ところで、私はlibcoreについて話していなかったので、私のコメントを誤解したかもしれません。liballocだけです。)
alexcrichton:
おっとごめん!コアアロケータインターフェイス(liballocにあります)は失敗しないように指定されていると思います!()、それらの上にあるプリミティブ(たとえば、ボックス演算子)だけです。
おそらく、ボックス構文を拡張して、このユースケースに対応するためにいつかOptionを返すことができるようにすることができます。絶対に再利用できるようにしたいからです。このコード!
これは言語設計の決定です。単一の操作のロジックだけでなく、考慮する必要があります(Box::new
、たとえば)しかし、それが言語の人間工学にどのように影響するか。 Return
メカニズムを使用してメモリ割り当てエラーを処理する場合、これらのエラーはほとんどどこでも発生し始めます。メソッドがヒープにメモリを割り当てない場合でも現在、将来的にはそれに頼る可能性があります。 APIを変更する必要があるため、突然、実装の単純な変更がスタックします。これは、セマンティックバージョニングではメジャーリリースを意味します。スワッピングやメモリキラーが存在する場合、メモリ不足の処理は信頼性が低く、有用ではないため、少しのメリットがあります(多くの場合、メモリ不足エラーが発生するずっと前にメモリの割り当てを停止する必要があります)。
私が見た提案された解決策の1つは、メモリ不足をパニックとして扱い、対応するタスクを巻き戻して終了することです。