2016-04-14 5 views
5

安全性が重要なプロジェクトでは、動的割り当てや割り当てられたメモリの解放はお勧めしません。プログラム実行の精緻化/初期化フェーズの間のみ可能です。安全性が重要なプロジェクトでの動的割り当ての代替方法(C)

私は静的な割り当てだけを行うべきか、動的な割り当てが全体のプログラムに悪影響を及ぼさないといういくつかの正当な理由を実行するという点でSWを実装すると主張します。この問題?どのような方法や、プログラムの初期化/精緻化中にいくつかの(ヒープ)メモリを割り当てたり、そこからメモリを割り当て/割り当て解除したりするような方法や例はありますか?あるいは、(安全性が重要な)プロジェクトで動的割り当てを本当にしたい場合は、この問題の解決策/代替案ですか?

答えて

10

このタイプの質問は、「過度な」制限なしに安全関連システム内で動的メモリ割り当てを使用できるようにしたい開発者によって最もよく尋ねられます。彼らが選んだときに、彼らが選んだときに、そして(おそらく)彼らが選んだときにその記憶を解放することである。

まず、この問題に取り組んでいます(重要なシステムでは動的メモリ割り当てを制限なく使用できますか)。次に、どのように(いつ、またはいつ)動的メモリ割り当てが使用されるかに関するいくつかの制限を受け入れるオプションに戻ってきます。

「安全性重視のプロジェクト」では、このようなことは一般的に不可能です。安全関連システムは、一般的に、特定の危険を軽減または排除することに関する義務的要件を有する。特定の危険を適切に緩和または除去しない(すなわち、要件を満たす)ことができないと、人々の死亡または負傷などの危険が生じる可能性があります。そのようなシステムでは、一般的には、あるレベルの厳格さに対して、ハザードが適切かつ確実に緩和または排除されることを決定する必要があります。この結果は、典型的には、決定論に関連する一連の要件です。適切な分析を通じて、システムが動作やタイミングなどの属性が厳密に指定されている特定の方法でアクションを完了するかどうかを判断する機能です。

制限なしで動的メモリ割り当てを使用すると、システムの一部が必要に応じて動作するかどうかを判断することは困難です。問題の種類には次のものがあります。

  • 未割り当てメモリの断片化。 Nバイトのメモリが利用可能であっても、連続したNバイトのメモリを割り当てる要求が確実に実行されることを保証することはできません。以前は複数の割り当てと割り当て解除が任意の順序で行われていた - 特にNバイトのメモリが利用可能であっても、それらは連続したパーセルにはないかもしれません。
  • 十分性。成功する必要のある重要なメモリ割り当てが実際に成功するという保証を提供することは、しばしば困難です。
  • 適切な放出。メモリがまだ必要なときに解放されるのを防ぎ(割り当てが解除されたメモリにアクセスする可能性があります)、不要になったメモリが実際に解放されるようにします(メモリリークを防ぐなど)。
  • タイムリーさ。上記の問題を緩和する試みは、割り当てまたは解放の時間が可変であり、予測不可能であり、潜在的に上限を持たないことを意味する。これらを処理するアプローチの例としては、フラグメンテーション(断片化の問題に対処するため)やガベージコレクション(十分な問題や適切なリリースに対処するため)などがあります。これらのプロセスには、時間と他のシステムリソースが必要です。割り当てを試みるときにそれらが完了した場合、メモリを割り当てる時間は予測不可能になります。メモリーを解放すると、メモリーを解放する時間が予測できなくなります。他の時に実行された場合、他の潜在的にクリティカルなコードの動作は予測できなくなる可能性があります(たとえば、アプリケーションが効果的に世界がフリーズするなど)。

これらの要因は、制限のない動的メモリ割り当てが、システムのタイミングまたはリソース使用の決定の要件内でうまく機能しないことを意味します。本質的に、システム要件には、いくつかの制限が課され、システムに応じて、強制される必要があります。

ダイナミックメモリ割り当ての制限が受け入れられる場合、オプションがあります。一般に、これらの技術は、ポリシー制約と、それらのポリシーへの遵守を奨励する(好ましくは、高批判システムにおいて実施する)技術的解決の両面でサポートする必要がある。ポリシーの施行は、技術的(自動化および手動による設計とコードレビュー、カスタマイズされた開発環境、コンプライアンステストなど)または組織的(例:主なポリシーを故意に回避する開発者を解任する)のいずれかです。

技術の例には、

  • ダイナミックアロケーションはまったくありません。すなわち静的割り当てのみです。
  • システムの初期化中にのみ動的メモリ割り当てを使用します。これには、事前に割り当てるために割り当てる必要のある最大量のメモリが必要です。メモリ割り当てに失敗した場合は、POST(パワーオン・セルフ・テスト)エラーのように扱います。
  • メモリを割り当てますが、絶対に解放しないでください。これはフラグメンテーションの問題を回避する傾向がありますが、システムが必要とするメモリ量の上限を決定することを困難にする可能性があります。
  • カスタム割り当て。システム(またはアプリケーション)は、汎用ライブラリ関数(例えば、選択されたプログラミング言語に関連するもの)を使用するのではなく、動的メモリ割り当てを明示的に管理する。これは通常、カスタムアロケータを導入し、ダイナミックメモリ管理のための汎用ライブラリ関数の使用を禁止(または無効化)することを意味します。カスタムアロケータは、特定のシステムのニーズを念頭に置いて明示的に設計する必要があります。
  • メモリ管理のボクシング。これは、アプリケーションがメモリプールを割り当て、関数が固定金額(または固定金額の倍数)をプールから要求する特定の種類のカスタム割り当てです。プールはアプリケーションによって固定されているため、プールからのメモリ使用量を監視し、メモリがなくなった場合にメモリを解放するアクションを実行するアプリケーションがあります。プールからの割り当てと割り当て解除は、(ダイナミックメモリ割り当てに関するより一般的な懸念事項の一部が管理されているため)予測可能に実行することもできます。重要なシステムには複数のプールがあり、それぞれは特定の機能セットによって排他的に使用されます。
  • パーティショニング。クリティカルではない機能がクリティカルな機能で使用するために確立されたメモリプールにアクセスすることを明示的に防止します。これにより、クリティカルな機能が必要なメモリにアクセスできることを保証し、低クリティカリティ機能の失敗が高クリティカリティ機能の失敗をトリガできないようにします。パーティショニングは、アプリケーション内、または(適切に認定された)ホストオペレーティングシステム内、またはその両方でシステムのニーズに応じて実行できます。

これらのアプローチのいくつかは、互いにサポートするために使用できます。

関連する問題