私は現在、メモリを含む低レベルのarduinoについて学んでいます。私の質問は、ヒープとスタックがメモリの反対側で成長するため、メモリ不足は両方が中央のどこかで出会った場合にのみ発生するのか、または一方が中央に到達したときに発生するのかということです。
2 に答える
- 「中間」の概念はありません
- 基盤となるオペレーティングシステム(存在する場合)がプロセスを管理する方法(プラットフォームにそのようなものがある場合)によっては、スタックのサイズが制限され、「残りのメモリ全体」よりもはるかに小さい場合があります。
- 基盤となるオペレーティングシステム(存在する場合)が仮想メモリ空間を管理する方法(プラットフォームにそのようなものがある場合)によっては、ヒープのサイズが制限され、「残りのメモリ全体」よりもはるかに小さい場合があります。
これらの制限のいずれかが設定されている場合、それらの地域が互いに出会う可能性はごくわずかです。実際には、おそらくそれらはより早く単にスペースを使い果たし、保護メカニズムは関連するハードウェアのソフトウェア例外を発生させます。
これは、「メモリ不足」イベントが1つではないことを意味します。スタックにはOOMがあり、ヒープにはOOMがあります。私の世界の一部では、伝統的に、スタックに関連するものはStackOverflow :)と呼ばれ、ヒープに関連するものはOutOf[Heap]Memoryです。
特に、プラットフォームに仮想メモリの概念がある場合、スタックはおそらく依然として単一のスペースブロックですが、ヒープはおそらくスパース構造であり、複数の分散したスペースブロックで構成され、必ずしも物理的に順序付けられているとは限りません。いくつかの昇順または降順の方法。そのような場合、何かに出会うことについて話すのは難しいです。StackOverflowは、スタックがサイズ制限に達したときに発生し、OutOfMemoryは、メモリマネージャーがメモリスペースに適切な空きホールを見つけられなかったときに発生します。
仮想メモリを無視する場合、および「生のハードウェア」についてのみ話す場合は、スタックが実際に配置されている場所によって異なります。IIRC(!)、一部の(実際には古い)プラットフォームでは、スタックは物理メモリの先頭にある事前定義されたスペース、たとえば最初の10ページに事前に割り当てられ、「一番下まで」大きくなりました。次に、ハードウェアにマップされたテーブルとポートステートイメージの数ページがあり、残りのテールはヒープでした。このような設定では、スタックポインタがゼロに達するとStackOverflowが発生します。プロセッサのステータスフラグを使用するとゼロの検出が簡単であるため、非常に「スマート」でした。また、これらの古いプロセッサでは、高いアドレスよりも低いアドレスに到達する方がはるかに簡単でした。したがって、頻繁にアクセスされるスタックを低いアドレスに配置することは大きなプラスでした。 。
IIRC(!)、新しいプラットフォームにはこれらの問題はありません(通常、NUMAなどは無視しましょう)。現在の従来の「生のハードウェア」セットアップでは、スペースの先頭に特別な領域(テーブル、ポートマップなど)を配置し、次にヒープを配置します。 、次に「空き領域」、次にスタック、そしてStackOverflowは、空き領域がなくなったとき、つまりスタックがすでにヒープによってブロックに出会ったときに発生します。StackOverflowはまだOutOfMemoryを意味しないことに注意してください。スタックがオーバーフローした可能性がありますが、ヒープにいくつかのギャップがあり、まだ多くの空き領域がある可能性があります。
これらの「IIRC」は重要であることに注意してください。私はArduinoと現在のプロセッサアーキテクチャの専門家ではありません。また、上記の「歴史的な」大げさな点は、新旧の点でかなりずれている可能性があります。私はそれに80%の確率を与えます。
スタックには特定の割り当てられたサイズがあり、そのサイズを超えると、スタックバッファオーバーフローが発生します。
ソフトウェアでは、コールスタックで使用されるメモリが多すぎると、スタックオーバーフローが発生します。コールスタックには限られた量のメモリが含まれており、多くの場合、プログラムの開始時に決定されます。
ソースウィキペディア