2

私はmmap(mmapがどのように機能するかを理解しよう)を使用して96kの匿名メモリを割り当てましたが、96kを64kと32kに分割したようです。ただし、960kを割り当てる場合、サイズが960kのチャンクを1つだけ割り当てます。ソラリスが割り当てメモリをいくつかの部分に分割するのはいつですか?コード:

#define PROT PROT_READ | PROT_WRITE
#define MAP  MAP_ANON  | MAP_PRIVATE
if ((src = mmap(0, 88304, PROT, MAP, -1, 0)) == MAP_FAILED)
    printf("mmap error for input");

if ((src = mmap(0, 983040, PROT, MAP, -1, 0)) == MAP_FAILED)
    printf("mmap error for input");

if ((src = mmap(0, 98304, PROT, MAP, -1, 0)) == MAP_FAILED)
    printf("mmap error for input");

トラス:

mmap(0x00000000, 88304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
    = 0xFFFFFFFF7E900000
mmap(0x00000000, 983040, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
    = 0xFFFFFFFF7E800000
mmap(0x00000000, 98304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
    = 0xFFFFFFFF7E700000

Pmap:

FFFFFFFF7E700000         64     -          -          - rw---    [anon]
    ==> strange is that for 96k, it was broken into 2 part.
FFFFFFFF7E710000         32     -          -          - rw---    [anon]
FFFFFFFF7E800000        960     -          -          - rw---    [anon]
FFFFFFFF7E900000         64     -          -          - rw---    [anon]
FFFFFFFF7E910000         24     -          -          - rw---    [anon]
FFFFFFFF7EA00000         64     -          -          - rw---    [anon]
FFFFFFFF7EA10000         32     -          -          - rw---    [anon]
4

3 に答える 3

3

それ連続した記憶です。アドレスでわかる(F...700000 + 64K = F...710000)ので、心配する必要はないと思います。アドレス空間に連続したメモリを提供するには、mmapが必要だと確信しています。それ以外の場合は、ベースアドレスが1つしかないため、まったく役に立ちません。2つの連続していないブロックがあると、その2番目のブロックを見つける方法はありません。

だから私はあなたの質問は:なぜこれがpmapに2つのブロックとして表示されるのですか?

私の答えは、「私が知っていれば詰め物をする」です。しかし、私はインテリジェントな推測をすることができます。これは、朝のこの時間に誰もが私に期待できる最高のものです(プレコーヒー)。

これらのブロックは、以前に別のプロセス(または2つ)に割り当てられ、mmapメモリマネージャーに解放されていたことをお勧めします。そのメモリマネージャがブロックを結合してより大きな空きブロックを作成する方法について、次の2つの可能性があります。

  • メモリが解放されるとすぐにそれを行います(出力がそれが起こっていないことを示している場合はそうではありません)。
  • それは定期的に実行され、96Kブロックを要求する前にそれを回避していませんでした。また
  • ブロックの割り当て中にそれを行うのに十分賢いので、それはまったく気になりません。

後者の理由は、メモリマネージャがリクエストに対して2つのブロックを提供することに問題がなかったため、明らかにそれを処理するように構築されているためだと思います。960Kブロックは、はるかに大きなブロックからのものであるため、おそらくセグメント化されていません。

これは推測であることに注意してください(情報はありますが、それでも推測です)。私はUNIXの内部をかなり見たことがありますが(実際のUNIXであり、ブロック上の新しい子供ではありません:-)、mmapを掘り下げる必要はありませんでした。

于 2009-05-08T02:17:57.273 に答える
3

その用語(ストライプ?スライス?ウェッジ?arg​​h)を思い出せませんが、Solarisはさまざまなサイズのプールからさまざまなページサイズを割り当てます。これは、メモリマッピングをより適切に使用するため、均一なページサイズよりもいくらか効率的であることがわかります。それらのサイズの1つは32K、別の64K、もう1つは1024Kだと思います。96Kを取得するには、64と32を取得し、960を取得するには、1024Kのほとんどを取得します。

このウィザードのコアリソースは、SolarisInternalsのです。残念ながら、私のものはお母さんのガレージの箱の中にあります。

于 2009-05-08T02:35:38.230 に答える
0

答えは、隣接することの意味によって異なります。Solarisとすべての最新のUnixおよびunixライクなシステム(おそらくすべての最新のオペレーティングシステム)は、物理メモリをページに分割し、「ページ」内のメモリは物理レベルで隣接します。最近のほとんどのシステムには、仮想アドレスを物理アドレスに変換するハードウェアMMU(メモリ管理ユニット)があります。したがって、mmapシステムコールは連続した仮想アドレス空間を返しますが、その仮想アドレスは、ページのサイズとメモリマッピングのサイズに応じて複数のページを使用する可能性のあるMMUによって管理されます。

すべての仮想アドレスは(マッピング内で)隣接しますが、「ページ」内のアドレスも物理的に隣接しますが、ページとページ間の遷移は物理的に互いに近接していない場合があります。

于 2014-01-17T17:24:28.513 に答える