문제

FastMM4에서보고 한 바와 같이 2MB 텍스트 파일의 메모리 누출 파일이있는 intraweb 앱을 상속했습니다. 나는 52 바이트가 누출되는 한 클래스의 115 인스턴스로 줄었다.

나쁜 배우에 대한 간단한 설명은 다음과 같습니다.

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은 유출 된 것과 그것이 창조 된 곳을 제공해야합니다.
그것은 그것을 실제 범인으로 좁히는 데 도움이 될 것입니다. 누가 누출되고 있습니까?

당신의 질문이 실제로 무엇인지 잘 모르겠습니다.
귀하의 코드는 불완전하거나 불완전하지 않습니다. 클래스에는 인터페이스 속성이나 인터페이스 개인 필드가 없으며 인터페이스를 반환하는 메소드에 불과합니다.

편집하다: ICWCCDSADAPTORNAV를 구현하는 객체의 코드를 보지 않으면 서 실제로 참조 계산되었는지 알 수 없습니다.
TinterfacedObject에서 내려 가지 않는 경우, 기회입니다 참조 계산이 아니라 이 자동으로 자유롭게 의존 할 수는 없습니다...

당신은 이것을보고 싶을 수도 있습니다 Coderage 2 세션: 인형에 대한 메모리 누출. 주로 Delphi의 메모리 누출을 방지/감지하기 위해 Fastmm을 사용하는 방법을 보여줍니다. D2007 이었지만 여전히 다른 버전과 관련이 있습니다.

다른 팁

당신은 지금까지 얼마나 빨리 작동하는지에 대한 좋은 답변을 얻었습니다. 그러나 실제 질문에 관해서는, 인터페이스 된 물체는 두 가지 다른 방식으로 누출 될 수 있습니다.

  1. 인터페이스는 _addref 및 _release 메소드에서 참조 계산을 구현 한 객체 인 경우에만 참조 카운트입니다. 일부 개체는 그렇지 않습니다.
  2. 원형 인터페이스 참조 (인터페이스 1 참조 인터페이스 2, 참조 인터페이스 1)이있는 경우 참조 카운트는 특별한 트릭 없이는 0으로 떨어지지 않습니다. 이것이 당신의 문제라면, 당신을 Andreas Hausladen 's에게 추천하겠습니다. 주제에 대한 최근 블로그 게시물.

해당 클래스의 115 인스턴스를 유출한다면 그 수업 그것은 유출되고 있습니다. 그 클래스가 차지하는 메모리는 그것이 지칭하는 것들이 차지하는 기억이 유출되고 있습니다. 어딘가에, 당신은 115 개의 인스턴스가 있습니다 TCwcBasicAdapter 당신이 자유롭지 않다는 것입니다.

뿐만 아니라, 속성 인터페이스 나 다른 유형에 관계없이 데이터를 저장하지 마십시오. 필드만이 메모리를 차지합니다 (컴파일러가 클래스를 대신하여 할당하는 숨겨진 공간과 함께).

그렇습니다. 당신은 잘못된 나무를 짖고 있습니다. 메모리 누출은 다른 곳에 있습니다. Fastmm이 메모리 누출이 있다고 말하면 유출 된 각 인스턴스가 어디에 할당되었는지 알려주지 않습니다. 그것은 그 능력을 가지고 있습니다. 해당 기능을 활성화하려면 조건부 컴파일 기호를 조정해야 할 수도 있습니다.

확실히 그렇지 않습니다 그러나 유출되는 해당 클래스의 사례. Fastmm은 또한 클래스의 인스턴스 또는 인터페이스를 구현하는 클래스와 같은 다른 것들을보고해야합니다.


추가 한 기능을 기반으로, 나는 그것이 정말로 TCwcCDSAdapterNavBase 그것은 유출되고 있으며, 그것은 당신이 그것을 만드는 데 사용하는 비정형적인 방식 때문일 수 있습니다. 예외 처리기가 GetAdapterNav 실행 중이 야? 나는 그것을 의심한다. TObject.GetInterface 명시 적으로 예외를 제기하지 마십시오. 객체가 인터페이스를 지원하지 않으면 반환됩니다. False. 예외 핸들러가 잡을 수있는 모든 것은 액세스 위반 및 불법 운영과 같은 것들입니다.

다음과 같이 해당 기능을보다 직접 구현할 수 있습니다.

if Assigned(FDataSet) then
  Result := TCwcCDSAdapterNavBase.Create(...);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top