Có cách nào để biết theo chương trình nếu khối bộ nhớ cụ thể không được giải phóng bằng FastMM?


103

Tôi đang cố gắng phát hiện xem một khối bộ nhớ chưa được giải phóng. Tất nhiên, người quản lý cho tôi biết điều đó bằng hộp thoại hoặc tệp nhật ký, nhưng nếu tôi muốn lưu trữ kết quả trong cơ sở dữ liệu thì sao? Ví dụ, tôi muốn có trong một bảng cơ sở dữ liệu tên của các quy trình đã phân bổ các khối đã cho.

Sau khi đọc tài liệu về FastMM, tôi biết rằng kể từ phiên bản 4.98, chúng tôi có khả năng được người quản lý thông báo về việc cấp phát bộ nhớ, giải phóng và phân bổ lại khi chúng xảy ra. Ví dụ OnDebugFreeMemFinishsự kiện đang chuyển cho chúng tôi một sự PFullDebugBlockHeaderkiện chứa thông tin hữu ích. Có một thứ PFullDebugBlockHeadercòn thiếu - thông tin nếu khối đã cho đã được giải phóng bởi ứng dụng.

Trừ khi OnDebugFreeMemFinishđược gọi chỉ cho các khối không được giải phóng? Đây là điều mà tôi không biết và muốn tìm hiểu.

Vấn đề là ngay cả khi kết nối với OnDebugFreeMemFinishsự kiện, tôi cũng không thể tìm hiểu xem liệu khối có được giải phóng hay không.

Đây là một ví dụ:

program MemLeakTest;

{$APPTYPE CONSOLE}

uses
  FastMM4, ExceptionLog, SysUtils;


procedure MemFreeEvent(APHeaderFreedBlock: PFullDebugBlockHeader; AResult: Integer);
begin
//This is executed at the end, but how should I know that this block should be freed
//by application? Unless this is executed ONLY for not freed blocks.
end;

procedure Leak;
var
  MyObject: TObject;
begin
  MyObject := TObject.Create;
end;

begin
  OnDebugFreeMemFinish := MemFreeEvent;
  Leak;
end.

Những gì tôi đang thiếu là gọi lại như:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

Sau khi duyệt qua nguồn của FastMM, tôi thấy rằng có một quy trình:

procedure LogMemoryLeakOrAllocatedBlock(APointer: PFullDebugBlockHeader; IsALeak: Boolean);

có thể bị ghi đè, nhưng có thể có một cách dễ dàng hơn?


7
Tôi luôn hiểu rằng FastMM chỉ có thể thực hiện kiểm tra này là hành động RẤT CUỐI CÙNG mà chương trình nên thực hiện - theo định nghĩa - vì vậy vào thời điểm FastMM đưa ra báo cáo, mã của bạn đã hoàn thành. Để có được một giải pháp từng phần, bạn luôn có thể xem nguồn của chúng để xem cách bộ nhớ được cấp phát được gắn cờ.
Brian Frost

6
Báo cáo như dự kiến ​​rò rỉ? Bạn đã đăng ký nó như mong đợi. Ngoài ra, bạn không thể quyết định rằng bộ nhớ bị rò rỉ cho đến khi tắt máy, trừ khi bạn cung cấp logic phức tạp hiểu được thời gian tồn tại dự kiến.
David Heffernan

6
Nếu OnDebugFreeMemFinishđược gọi có nghĩa là khối đã được giải phóng. Không có OnMemoryLeaksự kiện nào . Không bao giờ có thể có một sự kiện như vậy. Những gì FastMM làm là, khi tắt máy, xác định rằng bất kỳ khối nào chưa được giải phóng phải bị rò rỉ. Nó không thể phát hiện rò rỉ sớm hơn thế.
David Heffernan

12
Bất cứ khi nào FastMM cho tôi biết có sự cố rò rỉ bộ nhớ, tôi gỡ bỏ các công cụ và khắc phục nó ngay lập tức. Nếu bạn không làm điều đó thì bạn sẽ khó tái tạo lại vết rò rỉ. Nếu bạn thực sự muốn đăng nhập vào cơ sở dữ liệu thì bạn cần phải xem chức năng CheckBlocksOnShutdown. Một điểm mở rộng tiềm năng khác là AppendEventLognhưng bạn sẽ cần sửa đổi nguồn FastMM mà tôi nghi ngờ.
David Heffernan

12
Erm chỉ cần chọn tệp, phân tích cú pháp và đưa nó vào DB?
Tony Hopkinson

Câu trả lời:


2

Ngay cả khi trình xử lý như vậy tồn tại, nó sẽ gần như vô dụng, vì mọi thứ, bao gồm cả DB sẽ ngừng hoạt động vào thời điểm báo cáo FastMM bị rò rỉ.

Vì vậy, tôi khuyên bạn nên bật LogErrorsToFilecùng với các FullDebugModeđiều kiện trong FastMM4Options.inc. Điều này sẽ cung cấp cho bạn một tệp văn bản có rò rỉ, sau này bạn có thể phân tích cú pháp và đưa vào DB.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.