any tip/trick for avoid memory leak?
Posted: Thu Sep 19, 2013 2:13 pm
Thanks.
http://www.purebasic.com
https://www.purebasic.fr/english/
Thanks intelligent tip,luis wrote:Sure.
Deallocate what you allocate.
Read carefully the help of PB commands before using them to use them properly.
Read carefully API docs before using them to use them properly.
Use a tool to monitor resource allocations (OS objects) if available for your OS.
Report bugs in the tools you are using (compiler, libraries, etc.) since you can't fix them.
Use defensive programming (ASSERTS).
Put a log of debug checks in your debug builds.
Think about more intelligent ASSERTs to disseminate in your code.
Log to file some of the above if you distribute your programs for general use.
Without track/debug you can probably find the cause of a large leak. For a start, run a 'Find' on every List/Array/Image etc and check that each has a corresponding Free()I have project the memory grow from 300k to 100mb at end day, any tip for track/debug
Small start:sec wrote:I have project the memory grow from 300k to 100mb at end day, any tip for track/debug?
Code: Select all
Structure memInfo
*mem
lineNum.i
EndStructure
Global NewList memLeak_Allocs.memInfo()
Procedure AllocateMemory_New(size, flags, line)
Protected mem = AllocateMemory(size,flags)
If mem And AddElement(memLeak_Allocs())
memLeak_Allocs()\lineNum = line
memLeak_Allocs()\mem = mem
EndIf
ProcedureReturn mem
EndProcedure
Macro AllocateMemory(size, flags=0)
AllocateMemory_New(size, flags, #PB_Compiler_Line)
EndMacro
Procedure FreeMemory_New(mem)
ForEach memLeak_Allocs()
If memLeak_Allocs()\mem = mem
DeleteElement( memLeak_Allocs() )
EndIf
Next
FreeMemory(mem)
EndProcedure
Macro FreeMemory(mem)
FreeMemory_New(mem)
EndMacro
Procedure ShowAllocs()
If ListSize( memLeak_Allocs() )
Debug "-[ Allocated Memory ]------"
ForEach memLeak_Allocs()
Debug "Line: "+memLeak_Allocs()\lineNum+" Memory Handle: "+memLeak_Allocs()\mem
Next
Debug "---------------------------"
Else
Debug "-[ No memory allocated ]-"
EndIf
EndProcedure
;---------------
Dim p(100)
; alloc 100 areas
For i = 1 To 100
p(i) = AllocateMemory(1024)
Next
; free 95 areas
For i = 1 To 95
FreeMemory( p(i) )
Next
ShowAllocs()
; free remaining 5 areas
For i = 96 To 100
FreeMemory( p(i) )
Next
ShowAllocs()1st step:Removed the map -> to using the array, it's array of pointer struct.IdeasVacuum wrote:Without track/debug you can probably find the cause of a large leak. For a start, run a 'Find' on every List/Array/Image etc and check that each has a corresponding Free()I have project the memory grow from 300k to 100mb at end day, any tip for track/debug
Code: Select all
FinishCipher()
FinishDatabaseQuery()
FinishDirectory()
FinishFingerprint()
FinishFTPDirectory()
FinishMesh()Thanks bro,RichAlgeni wrote:Make sure any file manipulation is completed with CloseFile(fileNumber).
When passing strings to procedures, use pointers instead of the string.
Are you calling any external libraries?
Code: Select all
If OpenPreferences(GetPathPart(ProgramFilename())+"abc.ini")
PreferenceGroup("Info")
For i = 0 To ReadPreferenceLong("Num",0)-1
ac = ReadPreferenceString("Name" +Str(i), "")
If ac <> ""
For j = 1 To us
If *guest(j)\name$ = ac
*guest(j)\ip$=ReadPreferenceString("Address" +Str(i), "")
Break
EndIf
Next
EndIf
Next
ClosePreferences()
EndIfI don't know automatic way to check where it leaks. Just for checking that it leaks:sec wrote:- anyone has tip/trick for checking Handle leaks?
Code: Select all
Prototype pEmptyWorkingSet(hProcess)
Import "Kernel32.lib"
GetProcessHandleCount(hProcess,*pHandles.Long)
EndImport
Procedure EmptyWorkingSet_(hProcess)
PSAPI=OpenLibrary(0, "PSAPI.DLL")
If PSAPI
EWS.pEmptyWorkingSet=GetFunction(0, "EmptyWorkingSet")
If EWS
EWS(hProcess)
EndIf
CloseLibrary(0)
EndIf
EndProcedure
Procedure HandlesInfo()
Protected out$, ProcessHandle, handleCount.l
Shared start_time
ProcessHandle = OpenProcess_(#PROCESS_ALL_ACCESS,#False,GetCurrentProcessId_())
If ProcessHandle
EmptyWorkingSet_(ProcessHandle)
#HEAP_NO_SERIALIZE = 1
HeapCompact_(GetProcessHeap_(),#HEAP_NO_SERIALIZE)
GetProcessHandleCount(ProcessHandle,@handleCount)
out$ + "Handles: #"+ LSet(Str(handleCount),8)+" | "
out$ + "GDI: #" + LSet(Str(GetGuiResources_(ProcessHandle, 0)),4)+" | "
out$ + "User: #" + LSet(Str(GetGuiResources_(ProcessHandle, 1)),4)+" | "
out$ + "Runtime: " + FormatDate("%hh:%ii:%ss", ElapsedMilliseconds()/1000-start_time)
CloseHandle_(ProcessHandle)
EndIf
EnableDebugger
Debug out$
DisableDebugger
start_time = ElapsedMilliseconds()/1000
EndProcedure
start_time = ElapsedMilliseconds()/1000
HandlesInfo()