any tip/trick for avoid memory leak?

Just starting out? Need help? Post your questions and find answers here.
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

any tip/trick for avoid memory leak?

Post by sec »

Thanks.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: any tip/trick for avoid memory leak?

Post 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.
"Have you tried turning it off and on again ?"
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: any tip/trick for avoid memory leak?

Post 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?
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: any tip/trick for avoid memory leak?

Post 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()
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: any tip/trick for avoid memory leak?

Post 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.
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: any tip/trick for avoid memory leak?

Post 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?
Fred
Administrator
Administrator
Posts: 18349
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: any tip/trick for avoid memory leak?

Post by Fred »

Try to reduce your program size step by step until you find the line which leak.
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: any tip/trick for avoid memory leak?

Post 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.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: any tip/trick for avoid memory leak?

Post 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?
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: any tip/trick for avoid memory leak?

Post 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_() !!! ;)
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: any tip/trick for avoid memory leak?

Post by IdeasVacuum »

IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: any tip/trick for avoid memory leak?

Post by IdeasVacuum »

SetCapture_(hWnd) --> ReleaseCapture_()
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: any tip/trick for avoid memory leak?

Post 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 ...
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: any tip/trick for avoid memory leak?

Post 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.
Last edited by Danilo on Fri Sep 20, 2013 9:22 am, edited 2 times in total.
Fred
Administrator
Administrator
Posts: 18349
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: any tip/trick for avoid memory leak?

Post 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.
Post Reply