سؤال

لقد ورثت Intraweb التطبيق الذي كان 2MB ملف نصي من تسرب الذاكرة كما ذكرت من قبل FastMM4.لقد حصلت عليه إلى 115 من فئة واحدة تسريب 52 بايت.

وصف موجز سيئة الفاعل هو:

TCwcBasicAdapter = class(TCwcCustomAdapter)  
  protected  
    FNavTitleField: TField;  
    function GetAdapterNav(aDataSet: TDataSet): ICwcCDSAdapterNav; override;  
  public  
    constructor Create(aDataSource: TDataSource; aKeyField, aNavTitleField: TField; aMultiple: boolean);  
  end;  

واجهة هو:

  ICwcCDSAdapterNav = interface(IInterface)  

أنا الشجرة الخاطئة ، لأن الخاصية هي إشارة عدها ؟ هل هناك أي ظرف من الظروف حيث واجهة العقار يمكن أن تبقى فئة من كونها دمرت ؟

هنا هو تنفيذ الطريقة أعلاه:

function TCwcBasicAdapter.GetAdapterNav(aDataSet: TDataSet): ICwcCDSAdapterNav;
var
  AdapterNav: TCwcCDSAdapterNavBase;
begin
  result := nil;
  if Assigned(aDataSet) then begin
    AdapterNav := TCwcCDSAdapterNavBasic.Create(aDataSet, FKeyField.Index, FNavTitleField.Index);
    try
      AdapterNav.GetInterface(ICwcCDSAdapterNav, result);
    except
      FreeAndNil(AdapterNav);
      raise;
    end;
  end;
end;

مع الطبقة أعلن:

TCwcCDSAdapterNavBase = class(TInterfacedObject, ICwcCDSAdapterNav)
هل كانت مفيدة؟

المحلول

FastMM ينبغي أن تعطيك ما تسربت حيث تم إنشاؤه.
التي من شأنها أن تساعد في تضييق عليه إلى الجاني الحقيقي:الذي هو تسرب ماذا ؟

لست متأكدا حقا ما سؤالك ؟
الكود الخاص بك غير مكتملة أو لا أحد في السؤال:الفئة الخاصة بك لا يحتوي على واجهة العقار ولا واجهة حقل خاص فقط طريقة إرجاع واجهة التي هي غير مؤذية.

تحرير:دون رؤية رمز من وجوه الخاص بك تنفيذ ICwcCDSAdapterNav لا يمكننا معرفة ما إذا كان هو في الواقع إشارة عدها.
إذا كنت لا ينزل من TInterfacedObject, وهناك احتمالات أنه ليس مرجع حساب ، أنه لا يمكنك الاعتماد على هذا التلقائى تحرير...

قد ترغب في إعطاء نظرة على هذا CodeRage 2 الدورة: القتال تسرب الذاكرة for Dummies.أساسا يوضح كيفية استخدام FastMM لمنع/الكشف عن تسرب الذاكرة في دلفي.كان D2007 ولكن لا تزال ذات الصلة للحصول على إصدارات أخرى.

نصائح أخرى

كنت قد حصلت على بعض إجابات جيدة حتى الآن حول كيفية FastMM يعمل.ولكن كما الفعلية السؤال ، نعم ، وتفاعل الكائنات يمكن أن تسرب بطريقتين مختلفتين.

  1. واجهات هي المرجعية الوحيدة-تحسب إذا كانت الكائنات التي تنتمي إلى تنفيذ إشارة العد في _AddRef و _Release الأساليب.بعض الأشياء لا.
  2. إذا كان لديك دائري واجهة المراجع (واجهة 1 المراجع واجهة 2 التي مراجع واجهة 1,) ثم مرجع تسقط أبدا إلى 0 دون بعض الحيل الخاصة على الجزء الخاص بك.إذا كانت هذه هي المشكلة, سوف أشير لك إلى أندرياس Hausladen هو بلوق وظيفة الأخيرة في هذا الموضوع.

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

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

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

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


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

ويمكنك تنفيذ ذلك وظيفة بشكل مباشر مثل هذا:

if Assigned(FDataSet) then
  Result := TCwcCDSAdapterNavBase.Create(...);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top