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

Kevin Fishburne kevinfishburne at ...1887...
Thu Oct 31 02:40:48 CET 2013


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

-- 
Kevin Fishburne
Eight Virtues
www: http://sales.eightvirtues.com
e-mail: sales at ...1887...
phone: (770) 853-6271





More information about the User mailing list