سؤال

أرغب في تعيين ملف في الذاكرة باستخدام وظيفة MMAP وأرغب في معرفة ما إذا كانت مقدار الذاكرة الافتراضية على النظام الأساسي الحالي كافية لتعيين ملف ضخم. بالنسبة لنظام 32 ، لا يمكنني تعيين ملف أكبر من 4 جيجابايت.
سيكون std::numeric_limits<size_t>::max() أعطني مقدار الذاكرة القابلة للعنونة أم أن هناك أي نوع آخر يجب أن أختبره (OFF_T أو أي شيء آخر)؟

كما أشار كذبة ريان في تعليقه إلى أن "الذاكرة الافتراضية" هنا يساء استخدامها. ومع ذلك ، فإن السؤال يثبت: هناك نوع مرتبط بمؤشر ولديه أقصى قيمة تحدد الحد الأعلى لما يمكنك أن تمسك به على نظامك. ما هو هذا النوع؟ هل هو size_t أو ربما ptrdiff_t؟

هل كانت مفيدة؟

المحلول

size_t مطلوب فقط ليكون كبيرًا بما يكفي لتخزين أكبر كائن متجاور واحد ممكن. الذي - التي مايو لا تكون هي نفسها حجم مساحة العنوان (على الأنظمة ذات نموذج ذاكرة مجزأة ، على سبيل المثال)

ومع ذلك ، على المنصات الشائعة مع مساحة ذاكرة مسطحة ، فإن الاثنين متساوية ، وبالتالي يمكنك التخلص من استخدام size_t في الممارسة العملية إذا كنت تعرف وحدة المعالجة المركزية المستهدفة.

على أي حال ، هذا لا يخبرك حقًا بأي شيء مفيد. بالتأكيد ، يحتوي وحدة المعالجة المركزية 32 بت على مساحة ذاكرة سعة 4 جيجابايت ، وهكذا size_t هو عدد صحيح 32 بت غير موقعة. لكن هذا لا يقول شيئًا عن المبلغ الذي يمكنك تخصيصه. يتم استخدام جزء من مساحة الذاكرة بواسطة نظام التشغيل. ويتم استخدام بعض الأجزاء بالفعل من خلال تطبيقك الخاص: لتخطيط القابل للتنفيذ في الذاكرة (وكذلك أي مكتبات ديناميكية قد تستخدمها) ، لمكدس كل مؤشر ترابط ، تخصيص الذاكرة على الكومة وما إلى ذلك.

لذلك لا ، الحيل مثل أخذ حجم size_t يخبرك قليلاً عن مساحة العنوان التي تديرها ، ولكن لا شيء قابل للاستخدام للغاية. يمكنك أن تسأل نظام التشغيل عن مقدار الذاكرة المستخدمة من خلال عمليتك والمقاييس الأخرى ، ولكن مرة أخرى ، لا يساعدك ذلك كثيرًا. من الممكن أن تستخدم عملية ما يقتصر على بضع ميغابايت ، ولكن قد انتشرت ذلك على العديد من المخصصات الصغيرة بحيث من المستحيل إيجاد كتلة متجاورة من الذاكرة أكبر من 100 ميجابايت ، على سبيل المثال. وهكذا ، على جهاز 32 بت ، مع عملية لا تستخدم أي ذاكرة تقريبًا ، فمن غير المرجح أن تقوم بمثل هذا التخصيص. (وحتى لو كان لنظام التشغيل سحري WhatIsTheLargestPossibleMemoryAllocationICanMake() API ، ذلك ما يزال لن يساعدك. سيخبرك بما تحتاجه منذ لحظة. ليس لديك أي ضمان بأن الإجابة ستظل صالحة بحلول الوقت الذي حاولت فيه تعيين الملف.

حقًا ، أفضل ما يمكنك فعله هو محاولة لرسم خريطة الملف ، ومعرفة ما إذا كان يفشل.

نصائح أخرى

مرحبًا ، يمكنك استخدام GlobalMemoryStatusex و VirtualQueryex إذا كنت ترميز في Win32

الشيء هو أن حجم المؤشر لا يخبرك شيئًا عن مقدار "مساحة العنوان" المتاحة لك بالفعل ، أي يمكن تعيينه كقطعة واحدة متجاورة.

يقتصر على:

  • نظام التشغيل. قد يختار ذلك فقط إنشاء مجموعة فرعية من نطاق العناوين الممكنة من الناحية النظرية المتاحة لك ، لأن الذاكرة القابلة للتطبيق مطلوبة لأغراض OS-OND (مثل ، على سبيل المثال ، جعل FrameBuffer Card Card مرئيًا ، وبالطبع للاستخدام من قبل نظام التشغيل نفسه ).
  • حدود قابلة للتكوين. على Linux / Unix ، "Ulimit" command resp. تتيح SetRlimit () استدعاء النظام تقييد الحد الأقصى لحجم مساحة عنوان التطبيق بطرق مختلفة ، ولديه Windows خيارات مماثلة من خلال معلمات التسجيل.
  • تاريخ التطبيق. إذا كان التطبيق يستخدم رسم خرائط للذاكرة على نطاق واسع ، فيمكن أن يؤدي مساحة العنوان إلى الحد من الحد الأقصى لحجم العناوين الافتراضية المتجاورة "المتاحة".
  • منصة الأجهزة. بعض وحدات المعالجة المركزية لها مساحات عناوين مع "ثقوب" ؛ مثال على ذلك هو 64bit x86 حيث تكون المؤشرات صالحة فقط إذا كانت بين 0x0..0x7ffffffffff أو 0xFFFF000000000000 و 0xffffffffffffffffff. أي لديك 2x128tb بدلا من 16 ebb الكامل. فكر في الأمر على أنه مؤشرات "موقعة" 48 بت ...

أخيرًا ، لا تخلط بين "الذاكرة المتاحة" و "مساحة العنوان المتاحة". هناك فرق بين القيام malloc (someBigsize) و MMAP (... ، بعضها ، ...) لأن الأول قد يتطلب توافر الذاكرة المادية لاستيعاب الطلب بينما يتطلب الأخير عادةً توافرًا كبيرًا لا يشبه إلى حد كبير نطاق العنوان.

بالنسبة إلى منصات UNIX ، يتمثل جزء من الإجابة في استخدام GetRlimit (RLIMIT_AS) لأن هذا يعطي الحد الأعلى للاحتجاج الحالي لتطبيقك - كما قيل ، يمكن للمستخدم و/أو المسؤول تكوين هذا. أنت نضمن لك أي محاولة لمناطق MMAP أكبر من ذلك ستفشل.

إعادة سؤالك المعاد إعادة صياغة "الحد الأعلى لما يمكنك أن تمسك به على نظامك" ، هو مضلل إلى حد ما ؛ انها بنية الأجهزة محددة. هناك 64 بت بنية موجودة (X64 ، SPARC) التي يسمح MMU بسعادة (UINTPTR_T) (-1) كعنوان صالح ، أي يمكنك تعيين شيء ما في الصفحة الأخيرة من مساحة عنوان 64 بت. ما إذا كان نظام التشغيل يسمح للتطبيق بالقيام بذلك أم لا ، فهو مرة أخرى سؤال مختلف تمامًا ...

بالنسبة لتطبيقات المستخدمين ، فإن "العلامة العالية" ليست (دائمًا) ثابتة. إنه قابل للضبط على EG Solaris أو Linux. هذا هو المكان الذي يأتي فيه GetRlimit (RLIMIT_AS).

لاحظ أنه مرة أخرى ، من خلال المواصفات ، لن يكون هناك شيء لمنع تصميم نظام تشغيل (غريب) لاختيار على سبيل المثال وضع مداخن وأكوام "منخفضة" مع وضع الشفرة على عناوين "عالية" ، على منصة مع فتحات مساحة العنوان . ستحتاج إلى 64 بيلتات ، لا يمكن أن تجعلها أصغر ، ولكن قد يكون هناك عدد تعسفي من النطاقات "التي لا يمكن الوصول إليها / غير صالحة" والتي لم يتم إتاحتها لتطبيقك.

يمكنك المحاولة sizeof(int*). سيعطيك هذا طول (بايت) للمؤشر على النظام الأساسي المستهدف. وبالتالي ، يمكنك معرفة حجم المساحة القابلة للعنونة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top