이것은 메모리 누수가 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의 비공개 필드를 비우는 것이지만 오류가 발생합니다.
감사합니다,
폴 라이스
목록에있는 모든 개체가 목록을 소유하지 않은 경우이 개체는 어떻게 삭제됩니까? –
FreeAndNil은 클래스의 소멸자에있는 개인용 TObjectLists FCDSAdapters 및 FAdapter에서 호출됩니다. 반복적으로 FreeAndNil 전에 각 TCwcBasicAdapter에 대한 Remove를 호출하기 위해 코드를 두었습니다. 아무런 차이가 없었습니다. 두 가지 방법 모두 TList.Delete를 수행합니다. – user122603