سؤال

تطبيقنا فشل في كمبيوتر مستخدم واحد معين مع ERROR_NOT_ENOUGH_MEMORY ("لا توجد مساحة كافية لإتمام هذا الأمر").

يبدو أن الخطأ يرتفع في مكان عميق في إطار Delphi VCL الذي نستخدمه، لذلك لست متأكدا من وظيفة Windows API مسؤولة.

هل الذاكرة مشكلة؟ دعوة إلى GlobalMemoryStatus يعطي المعلومات التالية:

  • Dwtotalphys - 1063150000 (~ 1 GB)
  • dwavailphys - 26735000 (~ 27 MB)
  • dwavailpage - 1489000000 (~ 1.4 جيجابايت)

يبدو الأمر غريبا بالنسبة لي أن Windows سيتيح الذاكرة الفعلية المتاحة تصل إلى حد كبير عندما تتوفر مساحة كبيرة في ملف الترحيل، لكنني لا أعرف ما يكفي من إدارة الذاكرة الظاهرية لنظام Windows لمعرفة ما إذا كان هذا طبيعي أم لا. فعلا؟

إذا لم تكن الذاكرة، فما هو الحد من الموارد التي يجري ضربها؟ من ما قرأته عبر الإنترنت، ERROR_NOT_ENOUGH_MEMORY يمكن أن يكون نتيجة التطبيق ضرب أي حدود متعددة (كائنات GDI وكائنات المستخدمين والمقابض وما إلى ذلك) وليس بالضرورة الذاكرة. هل هناك قائمة شاملة بما يحد من نظام Windows يفرض؟ هل هناك أي طريقة لمعرفة الحد الذي يتم ضربه؟ حاولت جوجل، لكنني لم أستطع العثور على أي نظرة عامة منهجية.

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

المحلول 3

كان الجاني في هذه الحالة createcompatiblebitmap.. وبعد من الواضح أن النوافذ قد يفرض حدودا صارمة بشكل صارم على مستوى النظام على الذاكرة المتوفرة من الصور النقطية المعتمدة على الأجهزة (انظر، على سبيل المثال، مناقشة القائمة البريدية هذه)، حتى إذا كان نظامك لديه الكثير من الذاكرة والكثير من موارد GDI. (يبدو أن هذه الحدود النظامية لأن Windows قد تخصص الصور النقطية التي تعتمد على الجهاز في ذاكرة بطاقة الفيديو.)

الحل هو ببساطة استخدام الصور النقطية المستقلة للجهاز (dibs) بدلا من ذلك (على الرغم من أن هذه قد لا تقدم تماما من الأداء). هذه المادة KB يصف كيفية اختيار تنسيق DIB الأمثل للجهاز.

مرشحون آخرون لحدود الموارد (من إجابات الآخرين وأبحاثي الخاصة):

  • موارد GDI (من هذه الإجابة) - فحصها بسهولة gdiview.
  • تجزئة الذاكرة الافتراضية (من هذه الإجابة)
  • كومة سطح المكتب - انظر هنا أو هنا

نصائح أخرى

تحقق من كل الاحتمالات.

يمكن مراقبة مشاكل GDI باستخدام الحرة gdiview. جدوى. إنه ملف واحد يمكن للمستخدمين البدء بدون مثبت.

أيضا، تثبيت عملية المستكشف على الجهاز المعني.

إذا لم يكن لديك إمكانية الوصول إلى الجهاز، فاطلب من المستخدم أن يقوم بتشغيل لقطات من الحالة التي تم تشغيلها بواسطة التطبيقات. likeley جدا، وهذا سوف يمنحك بعض التلميح.

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

قد تكون إجابتي متأخرة بعض الشيء ولكن من تجربتي المتأخرة في تلك المشكلة نفسها، تقوم بجميع الاختبارات، بالخطوة خطوة بخطوة، مما يخلق DC، وإصداره، باستخدامه، باستخدامه DIBSection بدلا من CompatibleBitmap, باستخدام أدوات التسرب GDI / الذاكرة، إلخ.

في النهاية (لول) وجدت أن:

كنت تبحث عن أولوية هاتين المكالمتين، ثم تم إصلاح المشكلة بأكملها.

DeleteDC(hdc);       //do it first (always before deleting objects)
DeleteObject(obj);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top