2009-06-27 5 views
1

이것은 메모리 누수가 2MB 인 Intraweb 응용 프로그램을 상속받은 또 다른 게시물로, FastMM4에서보고 한 것처럼 한 클래스의 115 인스턴스가 각각 52 바이트 누출되었습니다.Multiply-referenced Objects 해제

누출은 다소 복잡하고 복잡한 인스턴스 생성 및 클래스 처리에서 비롯됩니다. 앱을 지금 작동 시키려면 클래스의 각 인스턴스화가 필요합니다. 그래서 나는 클론을 간단하게 정리하거나 다른 방법으로 참조하거나 클래스를 복제하는 몇 가지 방법을 찾고있다. 클래스

procedure TCwcDeclaration.AttachAdapter(DS: TDataSource; const FormName, KeyFN, TitleFN: string; const Multiple: boolean = False; 
    const AllowAttachment: boolean = False; const AllowComment: boolean = False); 
var 
    Forms : TCwcSessionForms; 
    Adapter: TCwcCDSAdapter; 
    KeyField, TitleField: TField; 
begin 
    Forms := GetForms(FormName); 
    KeyField := DS.DataSet.FindField(KeyFN); 
    TitleField := DS.DataSet.FindField(TitleFN); 
    Adapter := TCwcBasicAdapter.Create(DS, KeyField, TitleField, Multiple); 
    Adapter.AttachDBPersist(Self.DBPersist); 
    Forms.AttachDataAdapter(Adapter); 
    Forms.SetAllowAttachments(AllowAttachment); 
    Forms.SetAllowComments(AllowComment); 
end; 

procedure TCwcSessionForms.AttachDataAdapter(aCDSAdapter: TCwcCDSAdapter); 
var 
    Index: integer; 
begin 
    if (FCDSAdapters.IndexOf(aCDSAdapter) -1) 
    then raise Exception.CreateFmt('Duplicate Adapter attempting to be attached on %0:s', [FFormClassName]); 
    Index := FCDSAdapters.Add(aCDSAdapter); 
    if (FDefaultAdapterIndex = -1) 
    then FDefaultAdapterIndex := Index; 
end; 

번째 인스턴스 :

클래스 (TCwcBasicAdapter)의 첫 번째 인스턴스가 TObjectList와 (소유되지 않음)에 첨가하고 TObjectList와 함께 파괴 도착 로컬 변수 (FCDSAdapters) 인 TObjectList와 (소유되지 않음)에 첨가하고 TObjectList와 함께 파괴 도착 로컬 변수로서도 (FAdapters)

클래스의 인스턴스는 제 TempMulticast.AddObserver에서 관찰자 패턴의 일부이다
procedure TCwcCDSMulticastList.InitializeAdapters(const aSessionForms: TCwcSessionForms); 
var 
    i, Count: integer; 
    Adapter: TCwcCDSAdapter; 
    TempMulticast: TCwcCDSEventMulticast; 
begin 
    Count := aSessionForms.GetDataAdapterCount; 
    for i := 0 to Pred(Count) do begin 
     Adapter := aSessionForms.GetDataAdapter(i); 
     TempMulticast := FindDataSource(Adapter.DataSource); 
     if (TempMulticast = nil) then begin 
      TempMulticast := TCwcCDSEventMulticast.Create(Adapter.DataSource); 
      try 
      FMulticastList.Add(TempMulticast); 
      except 
      FreeAndNil(TempMulticast); 
      raise; 
      end; 
     end; 
     TempMulticast.AddObserver(Adapter); 
     FAdapters.Add(Adapter); 
    end; 
end; 

(어댑터) 라인 abov 이자형. 관찰자 (소유) TObjectList와 FObservers에 추가됩니다

procedure TCwcCDSEventMulticast.AddObserver(const aCDSAdapter: TCwcCDSAdapter); 
begin 
    FObservers.Add(TCwcCDSAdapterObserver.Create(aCDSAdapter)); 
end; 

constructor TCwcCDSAdapterObserver.Create(const aCDSAdapter: TCwcCDSAdapter); 
begin 
    inherited Create; 
    FOnStateChange  := aCDSAdapter.OnStateChangeIntercept; 
    FOnAfterDelete  := aCDSAdapter.AfterDeleteIntercept; 
    FInvalidateCursors := aCDSAdapter.InvalidateCursors; 
end; 

TCwcBasicAdapter는 FObservers가 파괴 될 때 정리, 여기에 있지 유출된다.

내가 시도한 가장 최근의 일은 FObservers를 소유하지 않기로 변경하여 어댑터의 개인 필드를 만들고 TCwcCDSAdapterObserver.Destroy의 비공개 필드를 비우는 것이지만 오류가 발생합니다.

감사합니다,

폴 라이스

+0

목록에있는 모든 개체가 목록을 소유하지 않은 경우이 개체는 어떻게 삭제됩니까? –

+0

FreeAndNil은 클래스의 소멸자에있는 개인용 TObjectLists FCDSAdapters 및 FAdapter에서 호출됩니다. 반복적으로 FreeAndNil 전에 각 TCwcBasicAdapter에 대한 Remove를 호출하기 위해 코드를 두었습니다. 아무런 차이가 없었습니다. 두 가지 방법 모두 TList.Delete를 수행합니다. – user122603

답변

0

당신은 자동 폐기 그들의 주인을하지 않고 스스로 개체를 삭제 할 수 있습니다 실현? 나는 당신이 자동화가 모든 경우에 일을하도록하려는 것처럼 느끼기 때문에 이것을 묻습니다.

1

목록이 소유자가 아닌 경우 목록이 해제 될 때 개체를 해제하지 않습니다. 각 항목에서 제거를 호출하면 해당 항목도 삭제되지 않습니다. 목록을 반복하고 목록의 각 항목에 대해 Free를 호출 한 다음 목록 자체를 비 웁니다.

목록 소유자를 만들면 목록을 비울 때이 작업을 수행하게됩니다.

+1

안녕하세요. 곱하기 참조 된 객체. 모든 목록을 소유 할 수는 없습니다. 그 이상은 위의 내용을 벗어났습니다. – user122603

+1

예, Count-1이어야합니다. 감사. 아니요, 모든 목록이 소유자가되는 것은 아닙니다. 당신이 그 물건을 해방시키고 싶은 사람들. 각 객체에는 정확히 한 명의 소유자가 있어야합니다. 개체를 만들어 로컬 변수에 할당하면 변수가 범위를 벗어나기 전에 해당 개체를 해제하거나 나중에 해제 할 개체로 개체를 전달해야합니다. 당신은 객체를 생성하고 소유자가 아닌리스트에 객체를 전달합니다. 그렇다면 개체를 소유 한 사람은 누구입니까? 그들은 어디에서 풀려나나요? – TrespassersW