ich bin mir sicher, dass zu diesem Thema schon einige Codes und Bibliotheken zusammengestellt wurden,
doch ich habe mir trotzdem mal die Zeit genommen, ein Include aus meiner Sammlung für alle anderen
Ausführbar zu machen.
Hierbei handelt es sich um eine Sammlung von Befehlen, die zum Aufspüren von Speicherlücken im
sehr hilfreich ist. Man muss in seinem Quellcode nur folgende Quelldatei einbinden und
den Befehl "MemoryManagerDebugGarbage()" ausführen, damit das Aufspüren beginnen kann.
Features:
- Noch nicht gelöschte Speicherbereiche können eingesehen werden
- Für jeden Speicherbereich wird der Name der Prozedur vermerkt, die den Speicherbereich erstellt hat
- Zusätzlich kann man bestimmten Speicherbereichen eigene IDs zuweisen
- Man kann das automatische Debuggen deaktivieren
- Die Liste (eigentlich Map) der registrierten Speicherbereiche kann jederzeit geleert werden
Code: Alles auswählen
;**************************************************************
; Memory manager
;
; Author: Josef Sniatecki
;**************************************************************
;******************************************
; Structures
;******************************************
Structure MemoryManagerEntry
ProcedureName.s
*Address
Size.i
ID.s
EndStructure
;******************************************
; Variables
;******************************************
Global NewMap MemoryManagerEntry.MemoryManagerEntry()
Global MemoryManagerEnableDebugging.i = #True
Global MemoryManagerID.i
;******************************************
; Declarations
;******************************************
Declare.i MemoryManagerAllocate(Size.i, Indentifier.s)
Declare.i MemoryManagerFree(*Memory)
Declare.i MemoryManagerFreeEntry(*Entry.MemoryManagerEntry)
Declare.i MemoryManagerReset()
Declare.i MemoryManagerEnableDebugging(State.i)
Declare.i MemoryManagerCount()
Declare.i MemoryManagerDebugGarbage()
;******************************************
; Functions
;******************************************
Procedure.i MemoryManagerAllocate(Size.i, Indentifier.s)
Static *Address
*Address = AllocateMemory(Size)
AddMapElement(MemoryManagerEntry(), Str(*Address))
MemoryManagerEntry()\Address = *Address
MemoryManagerEntry()\Size = Size
If Indentifier
MemoryManagerEntry()\ID = Indentifier
Else
MemoryManagerEntry()\ID = Str(MemoryManagerID)
MemoryManagerID + 1
EndIf
ProcedureReturn *Address
EndProcedure
Procedure.i MemoryManagerFree(*Memory)
FindMapElement(MemoryManagerEntry(), Str(*Memory))
If MemoryManagerEnableDebugging
Debug "Memory Manager: FREE <" + MemoryManagerEntry()\ID + ">"
Debug " CREATOR: " + MemoryManagerEntry()\ProcedureName
Debug " COUNT : " + Str(MapSize(MemoryManagerEntry()) - 1)
EndIf
DeleteMapElement(MemoryManagerEntry())
ProcedureReturn FreeMemory(*Memory)
EndProcedure
Procedure.i MemoryManagerReset()
ClearMap(MemoryManagerEntry())
MemoryManagerID = 0
EndProcedure
Procedure.i MemoryManagerEnableDebugging(State.i)
MemoryManagerEnableDebugging = State
EndProcedure
Procedure.i MemoryManagerCount()
ProcedureReturn MapSize(MemoryManagerEntry())
EndProcedure
Procedure.i MemoryManagerDebugGarbage()
If MemoryManagerEnableDebugging
ForEach MemoryManagerEntry()
Debug "Memory Manager: LOST <" + MemoryManagerEntry()\ID + ">"
Debug " CREATOR: " + MemoryManagerEntry()\ProcedureName
Debug " ADDRESS: " + Str(MemoryManagerEntry()\Address)
Debug " SIZE : " + Str(MemoryManagerEntry()\Size)
Next
EndIf
EndProcedure
Macro AllocateMemory(MemorySize, Indentifier = "")
MemoryManagerAllocate(MemorySize, Indentifier)
MemoryManagerEntry()\ProcedureName = #PB_Compiler_Procedure
If MemoryManagerEnableDebugging
Debug "Memory Manager: ALOC <" + MemoryManagerEntry()\ID + ">"
Debug " CREATOR: " + MemoryManagerEntry()\ProcedureName
Debug " COUNT : " + Str(MapSize(MemoryManagerEntry()))
EndIf
EndMacro
Macro FreeMemory(Memory)
MemoryManagerFree(Memory)
EndMacro
;******************************************
; Beispiel
;******************************************
DisableExplicit
; Folgende Daten sollen uns nicht interessieren, da sie
; während der ganzen Ausführung erhalten bleiben:
MemoryManagerEnableDebugging(#False)
*PreA = AllocateMemory(4)
*PreB = AllocateMemory(4)
*PreC = AllocateMemory(4)
; Da uns die eben erstellten Daten später nicht interessieren,
; löschen wir sie aus der MemoryManager-Tabelle:
MemoryManagerReset()
MemoryManagerEnableDebugging(#True)
; Nun erstellen wir zwei Speicherbereiche:
*A = AllocateMemory(4)
*B = AllocateMemory(4)
; Ein Speicherbereich wird gelöscht:
FreeMemory(*A)
; Nehmen wir an, dass auch der restliche Speicher (*A) zu löschen war,
; so können wir das folgendermaßen überprüfen:
Debug "---------------"
MemoryManagerDebugGarbage()
Debug "---------------"
; Falls man bestimmte Speicherbereiche vermerken möchte,
; so kann dies getan werden:
*C = AllocateMemory(4, "'C'-Memory")
Debug "---------------"
MemoryManagerDebugGarbage()

Gruß Josef