Autore Topic: Debug di una (apparente) perdita di memoria  (Letto 299 volte)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.297
  • Ne mors quidem nos iunget
    • Mostra profilo
Debug di una (apparente) perdita di memoria
« il: 29 Ottobre 2013, 15:49:09 »
Riporto questa discussione apparsa nella M.L. ufficiale:


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

--
Kevin Fishburne
"


" If you have a main loop somewhere, you can count the number of object
allocations at each loop, by using the Class.Count property:

Codice: gambas [Seleziona]
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.

--
Benoît Minisini
"


" I'm past my beer limit for programming (about 20 minutes ago), but thank
you. That's exactly the sort of thing I was looking for. Will give it a
try tomorrow to see what I find and will report back.

--
Kevin Fishburne
"
« Ultima modifica: 29 Ottobre 2013, 16:45:30 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re: Debug di una (apparente) perdita di memoria
« Risposta #1 il: 29 Ottobre 2013, 18:45:31 »
Ceskhonite? :skull:
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.297
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Debug di una (apparente) perdita di memoria
« Risposta #2 il: 31 Ottobre 2013, 15:00:10 »
...continua...


" I came up with this code to give a sorted, real-time display of
objects/classes in the "main loop":

---

Codice: gambas [Seleziona]
' 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
"


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

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
"


" Well, keep in mind that you use Shell also to send your statistics to
classes.sorted - in your main *loop*! Even if you are not grabbing the
Process object from the Shell instruction, it gets created. CMIIW, Benoit.

Maybe you can rewrite the code so that:
- you start a Konsole once (you already do that) but have it monitor
   some FIFO and sort the data coming from that FIFO;
- open a FIFO and write to it from the Gambas program instead of using
   Shell to sort the lines.

This way you don't create new objects regularly just because you are
printing your statistics.

I have attached a small project
(vedi allegato) which implements this idea. The only
interesting thing in there is the shell script because you have to start
multiple sort processes there to get your output "live". I don't know how
portable the script is to shells other than bash...

Hope this can help you.

Regards,
Tobi
"
« Ultima modifica: 31 Ottobre 2013, 15:03:17 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »