سؤال

أواجه مشاكل في تسرب الذاكرة البطيئة في تطبيق My Mode C ++ CLR .NET.

(IT I ++ المكتبات الثابتة الأصلية المرتبطة بتطبيق نماذج Windows VS2008 C ++ CLR مع إعداد برنامج التحويل البرمجي "/ CLR")

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

لقد حاولت استخدام العديد من الأدوات لتتبع تسرب الذاكرة بما في ذلك كل من أدوات تصحيح الأخطاء CRT التي تأتي مع Libs Visual Studio Crt Libs. لقد استخدمت أيضا أداة للكشف عن التسرب التجاري ("Remote Validator").

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

أداة (Validator Memory Validator) هي الإعداد لتتبع جميع استخدام الذاكرة (بما في ذلك Malloc، وتخصيص الذاكرة الظاهري الجديد ومجموعة كاملة من أنواع تخصيص الذاكرة الأخرى). في الأساس، تم تحديد كل إعداد له ذاكرة لتتبع الذاكرة.

تقارير الصورة .NET أنها تستخدم حوالي 1.5 ميغابايت من الذاكرة (من PerfMon).

إليك القليل النهائي من المعلومات: لدينا إصدار من التطبيق الذي يعمل كإجراء وحدة تحكم أصلية (أصلية بحتة - وليس CLR على الإطلاق). هذا هو 95٪ نفس الوضع المختلط إلا دون الاشياء واجهة المستخدم. هذا لا يبدو أن تسرب الذاكرة على الإطلاق، وقم بايت حوالي 5 ميغابايت بايت خاصة.

لذلك ما أحاول الوصول إليه هنا هو أنني لا أعتقد أن أي من التعليمات البرمجية الأصلية تسرب الذاكرة.

قطعة أخرى من اللغز: لقد وجدت أن هذا يشير إلى تسرب الذاكرة في تطبيقات الوضع المختلط عند الاستهداف 2.0 Framework (الذي أنا): http://support.microsoft.com/kb/961870.

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

هل لديكم أي اقتراحات؟

بعض الأشياء التي قد تساعدني:

  • هل هناك أي نوع آخر من مخصصات الذاكرة التي لا أتبعها؟
  • كيف تأتي الأرقام لا تضيف؟ أحصل على 5 ميغابايت من استخدام ذاكرة CRT، 1.5 ميغابايت من ذاكرة .NET فكيف يأتي التطبيق بالكامل يستخدم بايت 30 ميجابايت من القطاع الخاص؟ هل هذا مرتبط في إطار .NET؟ لماذا لا أرى هذه في أداة التسرب؟ لن يظهر .NET Framework كنوع من الذاكرة المخصصة؟
  • أي أدوات كشف تسرب أخرى تعمل بشكل جيد مع تطبيقات الوضع المختلط؟

شكرا على اي مساعدة

يوحنا

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

المحلول

حسنا، وجدت أخيرا المشكلة.

كان سبب وجود إعداد غير صحيح ل / EH (معالجة الاستثناء).

في الأساس، مع تطبيقات الوضع المختلط .NET، تحتاج إلى التأكد من تجميع جميع Libs المرتبطة بشكل ثابت مع / EHA بدلا من الافتراضي / EHS.

(يجب تجميع التطبيق نفسه أيضا مع / EHA، ولكن هذا معين - سيتم إبلاغ المترجم بالإبلاغ عن خطأ إذا كنت لا تستخدمه. المشكلة هي عند الارتباط في LIBS الثابتة الثابتة الأخرى.)

المشكلة هي أن الاستثناءات التي تم القبض عليها في القليل المدار من التطبيق، والتي تم إلقاؤها داخل المكتبات الأصلية التي تم تجميعها مع / EHS في نهاية المطاف لا تتعامل مع الاستثناء بشكل صحيح. لا يتم استدعاء المدمرين لكائنات C ++ بشكل صحيح.

في حالتي، حدث هذا فقط في مكان نادر، وبالتالي لماذا استغرق الأمر مني أعمار.

نصائح أخرى

مثل فورس كان يقول، ولكن بالنسبة ل C ++ / CLI؛) ....

لأي كائن تستخدمه في C ++ / CLI، إذا قمت بإنشاء المزيد من الكائنات من كود C ++، فيجب أن تحاول استخدام Seymantics تخصيص المكدس، على الرغم من أن هذا هو نوع محول المترجم من الأشياء، فإنه قادر على إعداد المتداخل __ry {} __fortally {} البيانات التي قد تستخدمها للاستخدام من التعليمات البرمجية الأصلية (التي يتم إعدادها بطريقة لا تفقد دعوة للتخلص منها).

نيش مقالة في مشروع التعليمات البرمجية هنا على C ++ / CLI STACK MENATION LISTICTICS جيدة جدا ويتذهب إلى عمق حول كيفية حظر استخدام {}.

يجب عليك أيضا تأكيد حذف أي كائن يتعهد غير قابل للانهيار لأنه لا يمكنك الاتصال بالتخلص في C ++ / CLI، حذف هذا يفعل ذلك من أجلك، إذا لم يكن استخدام دلالات المكدس ..

عادة ما أسمي قريبا من نفسي على التدفقات ومحاولة تعيين nullptr عندما انتهيت من كائن، فقط في حالة.

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

كملاذ أخير (أو ربما أولا :)، شيء واحد قمت به في الماضي هو الاستفادة من CLR Profiler API، هنا مقال آخر حول كيفية القيام بذلك، لدى كاتب المؤلف (Jay Hilyard) مثالا على ذلك إجابات؛

  • من كل نوع .NET يستخدم، كم عدد مثيلات الكائنات التي يتم تخصيصها؟
  • ما حجم مثيلات كل نوع؟
  • ما الإخطارات التي توفرها GC كما تذهب من خلال مجموعة القمامة وماذا يمكنك معرفة ذلك؟
  • متى يقوم GC بجمع مثيلات الكائنات؟

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

بالنظر إلى تعليقاتكم، هناك عدد قليل من الأشياء ...

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

هذا الأخير MSDN ماج, ، وثيقة المقالة الكثير من ذاكرة نوع perfmon sperlunking (متابعة هذا الأكبر سنا).

من vs perf بلوق, ، تظهر كيفية استخدام SOS في Visual Studio، والتي يمكن أن تكون مفيدة، لتتبع Rouge DLL، الوظائف ذات الصلة هي أيضا جيدة أيضا.

موني ستيفن بلوق و شركة, ، يقول إنه في فريق Perf، ولكن أساسا 100٪ من مشاركاته فيما يتعلق ب GC كثيرا، لذا فقد كتبه جيدا.

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

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

(بشكل سيصري، قد لا تعطيك تلك الإحصائيات الخاصة بهذه النظرة نظرة عالمية لما تنص على التعليمات البرمجية الخاصة بك، يمكنني أن أقول ذلك مؤخرا، لقد وجدت (حتى مع ثنائيات .NET4BETA، Profiler من هذه الشركة, ، جيد جدا، وهو قادر على اشتقاق التسريبات الأصلية / المدارة من آثار الملف الشخصي، يجلب لك مرة أخرى إلى خطوط المصدر الدقيق (حتى لو كان محسن، لطيفة جدا (ولديه تجربة لمدة 30 يوما)))).

حظ سعيد!! نأمل أن يساعد بعض هذا، إنه جديد فقط في ذهني، كما أفعل الكثير من نفس العمل الآن؛)

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

قد يكون لديك تسرب مرجعي، انظر إلى برنامج التنميط النمل. النمل profiler.

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

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

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

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