Page 1 of 2

any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 2:13 pm
by sec
Thanks.

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 2:35 pm
by luis
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.

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 2:43 pm
by sec
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.
Thanks intelligent tip,

I have project the memory grow from 300k to 100mb at end day, any tip for track/debug?

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 3:02 pm
by IdeasVacuum
I have project the memory grow from 300k to 100mb at end day, any tip for track/debug
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()

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 3:24 pm
by Danilo
sec wrote:I have project the memory grow from 300k to 100mb at end day, any tip for track/debug?
Small start:

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()
Try NoLeak - include to help you find memory leaks (PB5.20) by luis.

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 3:27 pm
by sec
IdeasVacuum wrote:
I have project the memory grow from 300k to 100mb at end day, any tip for track/debug
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()
1st step:Removed the map -> to using the array, it's array of pointer struct.

Nice tip: FreeArray(), never use it before.
Nice tip (Danilo): count(allocatememory) compare count(freememory)
What for next step?

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 6:22 pm
by Fred
Try to reduce your program size step by step until you find the line which leak.

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 10:00 pm
by BorisTheOld
@sec

The best way to avoid memory leaks is to start by writing very modular code. This will isolate functionality and make your code easier to maintain. Then add two extra procedures to each module:

1) Constructor (or Initiator)

In this procedure allocate all the resources that the module will use. Call this procedure before using the module for the first time.

2) Destructor (or Terminator)

In this procedure de-allocate all the resources allocated in the Constructor procedure. Call this procedure after using the module for the last time. If you dynamically allocate any memory in the Constructor, it's important to de-allocate it before you destroy anything that contains a pointer to it. For example, if you have an array of pointers to memory allocations, be sure to de-allocate the memory before you destroy the array. Otherwise you will have no way of knowing where the memory is in order to de-allocate it. In other words, you will have a memory leak.

Re: any tip/trick for avoid memory leak?

Posted: Thu Sep 19, 2013 10:09 pm
by RichAlgeni
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?

Re: any tip/trick for avoid memory leak?

Posted: Fri Sep 20, 2013 12:07 am
by Bisonte
Also don't forget :

Code: Select all

FinishCipher()
FinishDatabaseQuery()
FinishDirectory()
FinishFingerprint()
FinishFTPDirectory()
FinishMesh()
if you use the functions that these needed...
And on windows... the master of all memory leaks .... a forgotten CloseHandle_() !!! ;)

Re: any tip/trick for avoid memory leak?

Posted: Fri Sep 20, 2013 12:36 am
by IdeasVacuum

Re: any tip/trick for avoid memory leak?

Posted: Fri Sep 20, 2013 2:52 am
by IdeasVacuum
SetCapture_(hWnd) --> ReleaseCapture_()

Re: any tip/trick for avoid memory leak?

Posted: Fri Sep 20, 2013 5:40 am
by sec
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?
Thanks bro,
In this project, using OpenPreferences() releated to files, and calling one external lib too. for lib: i comented that calling lines; for file: it's closed after-use:

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()
  EndIf
For other check:
- NoLeak.pbi of luis: report 0 element leaks (for allocatememory, and two other checking)

Thanks you for other tips too,
- anyone has tip/trick for checking Handle leaks?

I am still tracking ...

Re: any tip/trick for avoid memory leak?

Posted: Fri Sep 20, 2013 9:08 am
by Danilo
sec wrote:- anyone has tip/trick for checking Handle leaks?
I don't know automatic way to check where it leaks. Just for checking that it leaks:
- PureMonitor for OS X
- PureMonitor for Windows

Windows:

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()
You can also try EmptyWorkingSet_() and HeapCompact_() in your program. If that helps, it is not a leak -
it is normal Windows behavior that the stack and the working set grows. Windows will automatically free
this, if it runs out of memory or resources.
Including EmptyWorkingSet_() and HeapCompact_() for debugging and finding memory leaks is OK.

Re: any tip/trick for avoid memory leak?

Posted: Fri Sep 20, 2013 9:11 am
by Fred
if you have linux version of your program, you can compile your PB program with '-ds' flag (to keep debug symbols) and run it with valgrind.