سؤال

لقد بدأت للتو في تجربة SDL في لغة C++، واعتقدت أن التحقق من تسرب الذاكرة بانتظام قد يكون عادة جيدة يجب تكوينها في وقت مبكر.

مع أخذ هذا في الاعتبار، كنت أقوم بتشغيل برامج "Hello World" الخاصة بي من خلال Valgrind لرصد أي تسريبات، وعلى الرغم من أنني قمت بإزالة كل شيء باستثناء الأساسيات SDL_Init() و SDL_Quit() البيانات، لا يزال Valgrind يُبلغ عن فقد 120 بايت ولا يزال من الممكن الوصول إلى 77 كيلو بايت.

سؤالي هو:هل هناك حد مقبول لتسرب الذاكرة، أم يجب أن أسعى جاهداً لجعل جميع التعليمات البرمجية الخاصة بي خالية تمامًا من التسرب؟

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

المحلول

كن حذرًا من أن Valgrind لا يلتقط نتائج إيجابية كاذبة في قياساته.

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

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

راجع للشغل أنا لست تابعًا لشركة IBM بأي شكل من الأشكال.لقد استخدمت للتو Purify على نطاق واسع وسوف أشهد على فعاليته.

يحرر:هنا مقالة تمهيدية ممتازة تغطية مراقبة الذاكرة.إنها عملية تنقية محددة ولكن المناقشة حول أنواع أخطاء الذاكرة مثيرة للاهتمام للغاية.

هث.

هتافات،

روب

نصائح أخرى

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

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

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

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

ويجب تجنب تعريفهم في المقام الأول، وتشغيل الأدوات التي وذكر آخرون لمحاولة الكشف عليهم.

وتجنب البرمجة قذرة - هناك المبرمجين سيئة بما فيه الكفاية هناك بالفعل - العالم لا يحتاج بعضها البعض

وتحرير

وأنا أتفق - يمكن أن العديد من الأدوات يوفر ايجابيات كاذبة

.

إذا كنت قلقًا حقًا بشأن تسرب الذاكرة، فستحتاج إلى إجراء بعض الحسابات.

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

الآن، سوف تحتاج إلى تقدير متوسط ​​طول جلسة البرنامج الخاص بك.على سبيل المثال، بالنسبة إلى notepad.exe، فإن 15 دقيقة تبدو تقديرًا جيدًا بالنسبة لي.

لو (متوسط ​​طول الجلسة)*(البايتات المسربة/الدقيقة)> 0.3*(مساحة الذاكرة التي تشغلها العملية عادةً), ، فربما يتعين عليك بذل المزيد من الجهود لتقليل تسرب الذاكرة.لقد قمت للتو بتكوين 0.3، استخدم المنطق السليم لتحديد الحد المقبول.

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

لتطبيق سطح المكتب، تسرب الذاكرة الصغيرة ليست مشكلة حقيقية. للخدمات (خوادم) أي تسرب الذاكرة مقبولة.

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

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

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

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

ويبدو بالفعل ان المطورين SDL لا تستخدم Valgrind، ولكن أنا في الأساس لا يهتمون إلا تلك بايت 120 المفقودة.

<اقتباس فقرة>   

ومع وضع هذا في الاعتبار، لقد تم تشغيل بلدي 'مرحبا العالم من خلال برامج Valgrind للقبض على أي تسرب، وعلى الرغم من أنني قمت بإزالة كل شيء ما عدا SDL_Init أبسط () وSDL_Quit () البيانات، Valgrind لا يزال تقارير 120 بايت المفقودة و77k تزال قابلة للوصول.

حسنا، مع Valgrind، "الذاكرة ما زالت قابلة للوصول" هو الذاكرة غالبا ما تكون غير تسربت حقا، خصوصا في مثل هذا البرنامج البسيط. أستطيع أن أراهن بأمان أن هناك أساسا لا تخصيص في SDL_Quit ()، وبالتالي فإن "التسريبات" هي هياكل مجرد تخصيص مرة واحدة من قبل SDL_Init ().

وحاول إضافة بعمل مفيد ومعرفة ما إذا تلك المبالغ الزيادة. محاولة جعل حلقة العمل المفيد (مثل خلق وتدمير بعض هيكل SDL) ومعرفة ما إذا كانت كمية التسرب ينمو مع كمية من التكرار. وفي الحالة الأخيرة، يجب عليك التحقق من آثار كومة من التسريبات واصلاحها.

وعلى خلاف ذلك، عد تلك التسريبات 77k باسم "الذاكرة التي يجب أن تتحرر في نهاية البرنامج، ولكن التي كانت تعتمد على نظام التشغيل لتحريرها.

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

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

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

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

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

ويمكنك استخدام آلية قمع valgrind (انظر --suppressions والقمعية --gen في صفحة رجل valgrind) ليقولوا ذلك لا يزعجك مع هذه الأخطاء.

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

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