نصائح

تحسين استخدام ذاكرة برنامج دلفي الخاص بك

تحسين استخدام ذاكرة برنامج دلفي الخاص بك



We are searching data for your request:

Forums and discussions:
Manuals and reference books:
Data from registers:
Wait the end of the search in all databases.
Upon completion, a link will appear to access the found materials.

عند كتابة تطبيقات طويلة الأمد - هذا النوع من البرامج التي ستقضي معظم اليوم في شريط المهام أو علبة النظام ، قد يصبح من المهم عدم ترك البرنامج "يهرب" باستخدام الذاكرة.

تعرف على كيفية تنظيف الذاكرة المستخدمة من قبل برنامج Delphi باستخدام وظيفة SetProcessWorkingSetSize Windows API.

01 من 06

ما الذي يفكر فيه Windows حول استخدام ذاكرة البرنامج؟

ألق نظرة على لقطة شاشة إدارة مهام Windows ...

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

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

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

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

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

02 من 06

عندما لإنشاء نماذج في تطبيقات دلفي الخاص بك

لنفترض أنك ستقوم بتصميم برنامج بالنموذج الرئيسي ونموذجين (مشروطين) إضافيين. عادةً ، وفقًا لإصدار Delphi الخاص بك ، ستقوم Delphi بإدراج النماذج في وحدة المشروع (ملف DPR) وستتضمن خطًا لإنشاء جميع النماذج عند بدء تشغيل التطبيق (Application.CreateForm (...)

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

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

إذا كان "MainForm" هو النموذج الرئيسي للتطبيق ، فيجب أن يكون النموذج الوحيد الذي تم إنشاؤه عند بدء التشغيل في المثال أعلاه.

يجب إزالة كل من "DialogForm" و "OccasionalForm" من قائمة "إنشاء النماذج تلقائيًا" ونقلها إلى قائمة "النماذج المتاحة".

03 من 06

تقليم الذاكرة المخصصة: ليست وهمية مثل ويندوز يفعل ذلك

ستانيسلو بيتل / غيتي إيمدجز

يرجى ملاحظة أن الاستراتيجية الموضحة هنا تستند إلى افتراض أن البرنامج المعني عبارة عن برنامج "التقاط" في الوقت الفعلي. ومع ذلك ، يمكن تكييفها بسهولة لعمليات نوع الدُفعات.

ويندوز وتخصيص الذاكرة

لدى Windows طريقة غير فعالة إلى حد ما لتخصيص الذاكرة لعملياته. يخصص الذاكرة في كتل كبيرة بشكل ملحوظ.

لقد حاول Delphi تقليل هذا إلى الحد الأدنى ولديه بنية إدارة الذاكرة الخاصة به والتي تستخدم كتل أصغر بكثير ولكن هذا غير مجدي فعليًا في بيئة Windows لأن تخصيص الذاكرة يعتمد في النهاية على نظام التشغيل.

بمجرد أن يقوم Windows بتخصيص كتلة من الذاكرة لعملية ، وتحرر هذه العملية 99.9٪ من الذاكرة ، سيظل Windows يرى أن الكتلة بأكملها قيد الاستخدام ، حتى لو تم استخدام بايت واحد فقط من الكتلة. والخبر السار هو أن Windows يوفر آلية لتنظيف هذه المشكلة. يوفر لنا الغلاف واجهة برمجة تطبيقات تسمى SetProcessWorkingSetSize. إليك التوقيع:

SetProcessWorkingSetSize (
h عملية: مقبض ؛
MinimumWorkingSetSize: DWORD؛
MaximumWorkingSetSize: DWORD)؛04 من 06

دالة واجهة برمجة التطبيقات (API) الكل القوية

سيريجيت جونجشاروينكولتشاي / آي إيم / غيتي إيمجز

حسب التعريف ، تقوم الدالة SetProcessWorkingSetSize بتعيين الحد الأدنى والحد الأقصى لأحجام مجموعة العمل للعملية المحددة.

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

إذا تم ضبط كل من الحد الأدنى والحد الأقصى للقيم على FFFFFFFF $ ، فسيقوم API بخفض حجم المجموعة مؤقتًا إلى 0 ، واستبدالها خارج الذاكرة ، وعلى الفور عندما تعود إلى ذاكرة الوصول العشوائي ، سيكون لها الحد الأدنى من الذاكرة المخصصة لذلك (كل هذا يحدث في بضع نانوثانية ، لذلك للمستخدم يجب أن يكون غير محسوس).

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

نحتاج إلى الانتباه لأمرين:

  1. المقبض المشار إليه هنا هو مقبض العملية وليس مقبض النماذج الرئيسية (لذلك لا يمكننا ببساطة استخدام "المقبض" أو "Self.Handle").
  2. لا يمكننا استدعاء واجهة برمجة التطبيقات هذه بشكل عشوائي ، نحتاج إلى محاولة الاتصال بها عندما يُعتبر البرنامج خاملاً. والسبب في ذلك هو أننا لا نريد تقليص الذاكرة في الوقت المحدد لأن بعض العمليات (نقرة زر ، ضغط ، عرض تحكم ، وما إلى ذلك) على وشك الحدوث أو يحدث. إذا تم السماح بحدوث ذلك ، فإننا نواجه خطرًا كبيرًا بحدوث انتهاكات وصول.
05 من 06

تقليم استخدام الذاكرة على القوة

صور البطل / صور غيتي

الغرض من وظيفة SetProcessWorkingSetSize API هو السماح بإعداد منخفض المستوى للحد الأدنى والحد الأقصى لذاكرة الذاكرة لمساحة استخدام الذاكرة في العملية.

فيما يلي دالة Delphi نموذجية تلتف استدعاء SetProcessWorkingSetSize:

إجراء TrimAppMemorySize.
فار
MainHandle: THandle؛
ابدأ
  محاولة
MainHandle: = OpenProcess (PROCESS_ALL_ACCESS ، false ، GetCurrentProcessID) ؛
SetProcessWorkingSetSize (MainHandle، $ FFFFFFFF، $ FFFFFFFF)؛
CloseHandle (MainHandle) ؛
  إلا
  النهاية;
Application.ProcessMessages.
النهاية;

عظيم! الآن لدينا آلية لخفض استخدام الذاكرة. العقبة الأخرى الوحيدة هي أن تقرر متى نسميها.

06 من 06

TApplicationEvents OnMessage + مؤقت: = TrimAppMemorySize الآن

صور مرسي / صور غيتي

في هذا الكود ، وضعناه كالتالي:

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

الآن ، تحقق دوريًا من آخر علامة التجزئة مقابل "Now" وإذا كان الفرق بين الاثنين أكبر من الفترة التي تُعتبر فترة خمول آمنة ، فقم بقص الذاكرة.

فار
LastTick: DWORD؛

إسقاط مكون ApplicationEvents في النموذج الرئيسي. في ه OnMessage أدخل معالج الأحداث الكود التالي:

إجراء TMainForm.ApplicationEvents1Message (فار Msg: tagMSG؛ فار التعامل معها: منطقية) ؛
ابدأ
  قضية Msg.message من
WM_RBUTTONDOWN،
WM_RBUTTONDBLCLK،
WM_LBUTTONDOWN،
WM_LBUTTONDBLCLK،
WM_KEYDOWN:
LastTick: = GetTickCount؛
  النهاية;
النهاية;

قرر الآن بعد أي فترة من الوقت ستعتبر البرنامج خاملاً. قررنا دقيقتين في حالتي ، لكن يمكنك اختيار أي فترة تريدها وفقًا للظروف.

إسقاط مؤقت في النموذج الرئيسي. اضبط الفاصل الزمني إلى 30000 (30 ثانية) وفي حدث "OnTimer" الخاص به ، قم بوضع التعليمات التالية المؤلفة من سطر واحد:

إجراء TMainForm.Timer1Timer (المرسل: TObject) ؛
ابدأ
  إذا ((((GetTickCount - LastTick) / 1000)> 120) أو (Self.WindowState = wsMinimized) ثم TrimAppMemorySize.
النهاية;

التكيف مع العمليات الطويلة أو برامج الدفعات

تكييف هذه الطريقة لأوقات المعالجة الطويلة أو عمليات الدُفعات بسيطة للغاية. عادةً سيكون لديك فكرة جيدة عن المكان الذي ستبدأ فيه العملية المطولة (على سبيل المثال بداية حلقة القراءة عبر ملايين سجلات قاعدة البيانات) وأين ستنتهي (نهاية حلقة قراءة قاعدة البيانات).

قم ببساطة بتعطيل المؤقت الخاص بك في بداية العملية ، وتمكينه مرة أخرى في نهاية العملية.


شاهد الفيديو: الشرح الكامل عن كاميرات المراقبة CCTV (أغسطس 2022).