如何在Delphi 7中追蹤內存中某個類的計數,而無需在類中添加靜態計數成員。 用於跟蹤程序性能。 先進的謝謝。如何跟蹤delphi中某個類的實例數?
1
A
回答
4
你可以連接在類VMT的NewInstance方法和FreeInstance方法:
unit ClassHook;
{no$DEFINE SINGLE_THREAD}
interface
var
BitBtnInstanceCounter: integer;
implementation
uses Windows, Buttons;
function GetVirtualMethod(AClass: TClass; const VmtOffset: Integer): Pointer;
begin
Result := PPointer(Integer(AClass) + VmtOffset)^;
end;
procedure SetVirtualMethod(AClass: TClass; const VmtOffset: Integer; const Method: Pointer);
var
WrittenBytes: {$IF CompilerVersion>=23}SIZE_T{$ELSE}DWORD{$IFEND};
PatchAddress: PPointer;
begin
PatchAddress := Pointer(Integer(AClass) + VmtOffset);
WriteProcessMemory(GetCurrentProcess, PatchAddress, @Method, SizeOf(Method), WrittenBytes);
end;
{$IFOPT W+}{$DEFINE WARN}{$ENDIF}{$WARNINGS OFF} // avoid compiler "Symbol 'xxx' is deprecated" warning
const
vmtNewInstance = System.vmtNewInstance;
vmtFreeInstance = System.vmtFreeInstance;
{$IFDEF WARN}{$WARNINGS ON}{$ENDIF}
type
TNewInstanceFn = function(Self: TClass): TObject;
TFreeInstanceProc = procedure(Self: TObject);
var
OrgTBitBtn_NewInstance: TNewInstanceFn;
OrgTBitBtn_FreeInstance: TFreeInstanceProc;
function TBitBtn_NewInstance(Self: TClass): TObject;
begin
Result := OrgTBitBtn_NewInstance(Self);
{$IFDEF SINGLE_THREAD}
Inc(BitBtnInstanceCounter);
{$ELSE}
InterlockedIncrement(BitBtnInstanceCounter);
{$ENDIF}
end;
procedure TBitBtn_FreeInstance(Self: TObject);
begin
{$IFDEF SINGLE_THREAD}
Dec(BitBtnInstanceCounter);
{$ELSE}
InterlockedDecrement(BitBtnInstanceCounter);
{$ENDIF}
OrgTBitBtn_FreeInstance(Self);
end;
procedure InstallHooks;
begin
OrgTBitBtn_NewInstance := GetVirtualMethod(TBitBtn, vmtNewInstance);
OrgTBitBtn_FreeInstance := GetVirtualMethod(TBitBtn, vmtFreeInstance);
SetVirtualMethod(Buttons.TBitBtn, vmtNewInstance, @TBitBtn_NewInstance);
SetVirtualMethod(Buttons.TBitBtn, vmtFreeInstance, @TBitBtn_FreeInstance);
end;
procedure RemoveHooks;
begin
SetVirtualMethod(Buttons.TBitBtn, vmtNewInstance, @OrgTBitBtn_NewInstance);
SetVirtualMethod(Buttons.TBitBtn, vmtFreeInstance, @OrgTBitBtn_FreeInstance);
end;
initialization
InstallHooks;
finalization
RemoveHooks;
end.
在程序中包含的任何uses
條款本機現在BitBtnInstanceCounter
將跟蹤TBitBtn
實例數。
編輯:如果有可能多個線程同時創建跟蹤類的對象,則需要使用互鎖訪問來修改計數器變量。請注意,第三方組件可以靜靜地使用線程,因此不定義SINGLE_THREAD
符號更安全。
3
有沒有內置的方式來做到這一點。某些分析器(AQTime?)通過安裝自定義堆管理器鉤子,然後查看位於任何對象開始處的類型指針,爲您生成此類度量標準。你可以自己做,但如果這是在開發過程中進行分析,那麼只要使用已經由其他人開發和測試的內容就容易多了。
相關問題
- 1. 在運行時,需要跟蹤某個類的實例數
- 2. 如何跟蹤一個類型實例的數量?
- 3. 在基類跟蹤實例
- 4. 如何跟蹤多個對象實例?
- 5. jQuery小部件:如何跟蹤實例?
- 6. 如何跟蹤Glassfish實例中的會話數量?
- 7. Delphi跟蹤工具
- 8. 我如何跟蹤同一個SKSpriteNode的個體實例
- 9. Ruby跟蹤實例變量
- 10. 如何跟蹤同一用戶(對象)的多個實例
- 11. 如何跟蹤DataTemplate的所有實例或DataTemplate中的控件?
- 12. 如何在C#中跟蹤應用程序的打開實例
- 13. 如何跟蹤Ruby中類之外的實例變量的更改?
- 14. 如何從類中的某個函數返回一個類的實例?
- 15. 如何跟蹤OData中的實體?
- 16. 如何實現一個跟蹤欄
- 17. ASP.Net MVC核心 - 實體類型「」的實例無法被跟蹤,因爲這種類型的使用相同的密鑰的另一個實例已被跟蹤
- 18. EF:實體類型X的實例無法被跟蹤,因爲這種類型的使用相同的密鑰的另一個實例已被跟蹤
- 19. 實體類型「TestType」的實例無法被跟蹤,因爲這種類型的使用相同的密鑰的另一個實例已被跟蹤
- 20. 模塊的Mixin實例跟蹤
- 21. 跟蹤已創建實例的列表
- 22. Entity Famework core - 實體類型的實例無法跟蹤,因爲具有相同密鑰的此類型的另一個實例已被跟蹤
- 23. 實體類型'xTestType'的實例無法跟蹤,因爲具有相同鍵的此類型的另一個實例已被跟蹤?
- 24. 如何跟蹤VC++中的某個對象6
- 25. 如何跟蹤某些屏幕打開?
- 26. 在Delphi中跟蹤訪問衝突
- 27. 如何跟蹤在delphi 10中通過NetHttpClient上傳的進度?
- 28. 我如何跟蹤一個人去某個地方的時間?
- 29. 如何基於某個類實例化特定的實現?
- 30. 某個端口的跟蹤路由
如果這個類有它自己的(虛擬的或不是)的構造函數和析構函數,並且它足夠長,你可以查看鉤住這些的代碼,以便你可以在其他地方進行計數。 madCodeHook(http://madshi.net)是一個衆所周知的庫。 –
@WarrenP:可能是因爲他沒有源代碼,或者它是您不想更改源代碼的組件,即使您擁有它。 –
是的。我只是想到了。如果這只是表現,那麼只有一個答案是理智的;購買AQTIME。殘酷的昂貴,是的。討厭的一點HASP許可廢話附加到它。是。但是,真棒工具。 –