[Gambas-user] debugging a (apparent) memory leak

Benoît Minisini gambas at ...1...
Thu Oct 31 08:09:32 CET 2013


Le 31/10/2013 02:40, Kevin Fishburne a écrit :
> On 10/28/2013 10:36 PM, Benoît Minisini wrote:
>> Le 29/10/2013 03:27, Benoît Minisini a écrit :
>>> Le 29/10/2013 02:20, Kevin Fishburne a écrit :
>>>> I don't think it's always been like this, but when I sometimes forget to
>>>> close the server app running on my physical server and it runs for a few
>>>> days I notice gb3 is using all 8 GB of system RAM and several GB of the
>>>> swap partition. There's nothing in the app (that I know of) that should
>>>> ever be using that much memory, so it sounds like a memory leak.
>>>>
>>>> Is there a way, other than manually following the logic of the entire
>>>> execution sequence, to identify what part of the code is continually
>>>> sucking up more and more RAM?
>>>>
>>>> Also, other than the infamous GOSUB without a corresponding RETURN, what
>>>> types of declarations or code logic should I look for if I do scan
>>>> through the codebase? Red flags, in other words.
>>>>
>>> If you have a main loop somewhere, you can count the number of object
>>> allocations at each loop, by using the Class.Count property:
>>>
>>> Dim hClass As Class
>>> For Each hClass In Classes
>>>       Print hClass.Name;;hClass.Count
>>> Next
>>>
>>> Then you can see which kind of object allocation grows indefinitely.
>>>
>> Another possibility would be an array whose size grows indefinitely too,
>> but the last method won't allow you to detect it.
>>
>
> I came up with this code to give a sorted, real-time display of
> objects/classes in the "main loop":
>
> ---
>
>     ' General declarations.
>     Dim hClass As Class
>     Dim DebugFile As File
>
>     ' Debug memory leaks.
>     If Rnd(0, 1000) < 5 Then  ' Shitty timer requiring no variable.
>       If Not Exist(System.User.Home & "/classes.sorted") Then Shell
> "konsole -e watch \"cat " & System.User.Home & "/classes.sorted\""
>       DebugFile = Open System.User.Home & "/classes" For Write Create
>       For Each hClass In Classes
>         Write #DebugFile, hClass.Count & " " & hClass.Name & gb.CrLf

--> Please use Print. And gb.CrLf is not the end-of-line separator on Unix.

>       Next
>       Close #DebugFile
>       Shell "sort -g -r " & System.User.Home & "/classes > " &
> System.User.Home & "/classes.sorted"
>     Endif
>
> ---
>
> As with Benoît's example it requires no other code and should be placed
> within the main loop. I use KDE, so if you want this to work in GNOME or
> whatever you'll need to change the "konsole" command and parameter (-e)
> to something else. There's probably a much more elegant way to do it but
> I'm not a bash expert.
>
> The results are in, and the server continually increments a class called
> "Process". The only thing in the codebase that uses that word is this
> declaration:
>
> Public PadDevice As Process ' Device to accept gamepad input.
>
> The client sets this up with:
>
> PadDevice = Exec ["cat", "/dev/input/js0"] For Read As "Gamepad"
>
> I've checked (set breakpoints at all references) and only the client
> code does anything with this. The client code does not increment the
> Process class or anything else abnormally, only the server code. Any
> ideas what object could be described as Process that is not declared as
> a Process?
>
> The first procedure to execute is Render.Main (the startup procedure).
> It then calls Render.Initialize, which shows the SDL screen and starts
> the Render.Screen_Draw procedure looping. This logic is the same for the
> server and the client (same program, different execution logic). The
> Render.Screen_Draw procedure checks to see if the program is running as
> the server or a client and calls the appropriate render procedure
> (Render.Screen_Server or Render.Screen_Client), which when finished
> returns control back to Render.Screen_Draw. I don't see any recursion
> there, so I'm at a loss as to what "Process" could be.
>
> The good news is that I've found an object incrementing indefinitely on
> the server, confirming my suspicion that there is in fact a memory leak.
>

If you call EXEC or SHELL, you create a new instance of Process. Check 
that you don't keep any reference on this instance indefinitely, and 
that the process really terminates (otherwise you will see them 
accumulating with the 'ps' command).

Regards,

-- 
Benoît Minisini




More information about the User mailing list