質問

mmap 関数を使用してファイルをメモリにマップしたいのですが、現在のプラットフォームの仮想メモリの量が巨大なファイルをマップするのに十分であるかどうかを知りたいです。32 システムの場合、4 GB を超えるファイルをマッピングできません。
するだろう std::numeric_limits<size_t>::max() アドレス指定可能なメモリの量を教えてください。それともテストする必要がある他のタイプ (off_t など) はありますか?

Lie Ryan がコメントで指摘したように、ここでの「仮想メモリ」は悪用されています。しかし、次のような疑問が残ります。ポインターに関連付けられた型があり、その型にはシステム上でアドレス指定できるものの上限を定義する最大値があります。このタイプは何ですか?それはsize_tですか、それともptrdiff_tですか?

役に立ちましたか?

解決

size_tのみが最大の可能性単一の連続したオブジェクトを格納するのに十分な大きさであることが必要です。すなわち、はない(例えば、セグメント化メモリ・モデルを持つシステム上の)アドレス空間のサイズと同じであってもよい。

しかし、フラットなメモリ空間と共通のプラットフォーム上で、両者が等しく、あなたがターゲットCPUを知っていれば、あなたが実際にsize_tを使用して逃げることができるようにます。

とにかく、これは本当にあなたに有益な何かを教えてくれありません。確かに、32ビットCPUは、4GBのメモリ空間を有しており、size_tように32ビットの符号なし整数です。しかし、それはあなたが割り当てることができますどのくらいについては何も言いません。メモリ空間の一部は、OSによって使用されます。 、各スレッドのスタックのために、メモリに実行ファイルをマッピングするため(だけでなく、それが使う可能性のあるダイナミックライブラリ)ヒープ上に割り当てられたメモリなど

:そして、いくつかの部分は、すでに独自のアプリケーションで使用されています。

はありませんので、そのようsize_tの大きさを取るなどのトリックは、あなたがに実行しているアドレス空間について少し伝えていないが、非常に使えるもの。多くのメモリは、プロセスおよびその他のメトリックで使用されているどのようにOSを頼むことができますが、再び、それは本当に多くのお手伝いをしていません。プロセスはメガバイトだけのカップルを使用しますが、それが100MBを超えるメモリの連続ブロックを見つけることは不可能だということ以上のように多くの小さな割り当てをそのスプレッドを持つことが可能である、と言います。だから、32ビットマシン上で、ほとんどありませんメモリを使用するプロセスで、あなたはこのような割り当てを行う可能性は低いだろう。 OSはがまだがあなたを助けないだろうと。それは瞬間からの前にあなたが必要なもの<全角>を教えてくれます。あなたが保証はありません、魔法WhatIsTheLargestPossibleMemoryAllocationICanMake()のAPIを持っていた(そして場合でも、答えはまだあなたがファイルをマップしようとした時点で有効であろうと。

だから、本当に、あなたができる最善のは、の試みのファイルをマップし、それが失敗したかどうかを確認する。

他のヒント

あなたは、Win32

でコーディングした場合、

こんにちは、あなたがGlobalMemoryStatusExとVirtualQueryExを使用することができます

問題は、ポインタのサイズからは、その「アドレス空間」のどれだけが実際に利用可能であるかについては何もわかりません。単一の連続したチャンクとしてマッピングできます。

以下によって制限されます。

  • オペレーティングシステム。マッピング可能なメモリは OS 自体の目的 (たとえば、グラフィックス カードのフレームバッファを可視にするなど、もちろん OS 自体で使用するため) に必要であるため、理論的に可能なアドレス範囲のサブセットのみを利用可能にすることを選択する場合があります。 )。
  • 設定可能な制限。Linux/UNIX では、「ulimit」コマンドがそれぞれsetrlimit() システム コールを使用すると、アプリケーションのアドレス空間の最大サイズをさまざまな方法で制限できます。Windows には、レジストリ パラメーターを介して同様のオプションがあります。
  • アプリケーションの履歴。アプリケーションがメモリ マッピングを広範囲に使用する場合、アドレス空間が断片化し、「利用可能な」連続仮想アドレスの最大サイズが制限される可能性があります。
  • ハードウェアプラットフォーム。一部の CPU には「ホール」のあるアドレス空間があります。その例は 64 ビット x86 で、ポインターは 0x0..0x7fffffffffff または 0xffff000000000000 と 0xffffffffffffffff の間にある場合にのみ有効です。つまり、完全な 16EB ではなく 2x128TB があります。これを 48 ビットの「署名付き」ポインターと考えてください。

最後に、「利用可能なメモリ」と「利用可能なアドレス空間」を混同しないでください。malloc(someBigSize) と mmap(..., someBigSize, ...) の実行には違いがあります。前者はリクエストに対応するために物理メモリの可用性を必要とする可能性があるのに対し、後者は通常、十分な大きさの空きメモリの可用性のみを必要とするためです。アドレス範囲。

UNIX プラットフォームの場合、答えの 1 つは getrlimit(RLIMIT_AS) を使用することです。これにより、アプリケーションの現在の呼び出しに上限が与えられます。前述したように、ユーザーおよび/または管理者がこれを構成できます。それより大きい領域を mmap しようとすると必ず失敗します。

あなたの言い換え質問日時「の上限どのようなことができますお使いのシステム上で、おそらく住所」、やや誤解を招くです。それは、ハードウェアアーキテクチャ固有のです。あなたは64ビットのアドレス空間の最後のページに何かをマップすることができ、有効なアドレスとして、すなわち - (1)そこに64ビットアーキテクチャを持つMMUは喜んことができます(uintptr_tを)(のx64、SPARC)があります。オペレーティングシステムは、アプリケーションが行うことができますかどうかそうではない全く別の問題... 再びです

は、ユーザアプリケーションの場合、「ハイマーク」しない(常に)で事前固定されています。これは、例えば上で調整可能ですSolarisまたはLinux。それのどこはgetrlimit(RLIMIT_AS)が入って来ます。

再び、仕様により、例えば選択する(奇妙な)オペレーティングシステムの設計を阻止するものは何もないだろうと

注「高」のアドレスにコードを入れつつ、アドレス空間の穴を持つプラットフォーム上で、「低」のアドレスにアプリケーション・スタックとヒープを置きます。あなたはどんな小さなそれらを作ることはできませんが、あなたのアプリケーションに利用できるようにされていませんでし「アクセス不可/無効」の範囲の任意の数があるかもしれません、そこに完全な64ビットのポインタを必要と思います。

あなたはsizeof(int*)を試すことができます。これはあなたのターゲットプラットフォーム上のポインタの長さ(バイト単位)を提供します。したがって、あなたは、アドレススペースがいかに大きな見つけることができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top