2

Linux は、スタックに割り当てられている場合、使用されなくなったときにメモリを再利用しません。

ヒープ

ヒープに 1GB を動的に (malloc/mmap) 割り当てます。

  • 割り当て前:

$トップ

仮想メモリ 1GB

常駐メモリ ~ 0

  • メモリセット 1GB

$トップ

仮想メモリ 1GB

常駐メモリ 1GB

  • 1GB の割り当て解除 (free/munmap) - 期待どおりに回収

$トップ

仮想メモリ 1GB

常駐メモリ ~ 0

スタック

スタックに 1GB を動的に割り当てます。

  • 前:

$トップ

仮想メモリ 1GB

常駐メモリ ~ 0

  • メモリセット 1GB

$トップ

仮想メモリ 1GB

常駐メモリ 1GB

  • 1GB の割り当て解除 (スタックの巻き戻し) - 割り当て解除後でも、常駐メモリは 1GB のままです! なんで?

$トップ

仮想メモリ 1GB

常駐メモリ 1GB

スタックが常駐メモリをアンワインドするとき (物理ページはまだ使用中) はなぜですか?

ヒープ セグメントの割り当ては mmap で行われ、スタック セグメントの割り当ては mmap で行われます。では、なぜリクレイムの動作に違いがあるのでしょうか?

4

1 に答える 1

3

OSは、スタックを一度使用すると、おそらくもう一度使用すると見なすためです。OS は、[アプリケーションの外部から] アプリケーションが将来何をしようとしているのかを実際に知ることはできません。スタックの一部を解放しても問題ないかどうかを判断するのはかなり難しく、スタックを減らすためだけにアプリケーションの実行を停止する必要がある OS であらゆる種類の興味深い競合状態が発生します。再度必要になるため、割り当てる必要があります。

mmap一方、を使用munmapすると、「このメモリには興味がありません」とOSに伝える明確な方法があります。そのため、その場で解放されます [munmap 呼び出し自体の一部として - 具体的にはzap_pte_range、ページ自体が解放され、OS に戻されます。

次の条件が満たされない限り、大きな問題にはなりません。 1. スワップを持たない組み込みシステムで実行している。2.アプリケーションは、多くのスタックを使用するために返された後、長時間実行されます(スタックとしてこれだけのメモリが実際に必要であると仮定すると、必要なときにそのメモリを使用できるようにする必要があるため、明らかにアプリケーションが後でスタックを必要とせず、その期間が長い場合の問題-長い定義が何であれ)。3. お使いのシステムには、他のアプリケーションでの他の RAM のニーズを満たすのに十分な RAM がありません。

私がそう言う理由は、スタックがそれだけ多くのメモリを使用しているにもかかわらず、アプリケーションがRAMを長時間使用しておらず、システムのメモリが不足している場合、システムはそれをディスクにスワップアウトしてスワップするためです。必要に応じて後の段階で。

また、このような大量のスタックスペースを使用することは、一般的に悪い考えだと考えられています。スタックのスペース不足 [制限に達するか、「利用可能なメモリが不足しています」] は、ほぼ常に致命的です。

そのため、スタックスペースを使用して一時変数を保存することをよく提案しますが、1GB のスタックはかなり過剰だと思います。数メガバイトは許容できるはずですが、数百メガバイト以上はおそらく「別の方法で保存する必要がある」ことを示しています。

于 2013-01-17T23:40:33.337 に答える