Memory Leak
#1
Never noticed it before but my menu selection screens have a memory leak! It keeps adding about 8MB/s of system memory. It is a pretty forward loop and the MOUSE calls are not the source (they were all commented out when I was trying to locate the source of the leak). I am really at a loss here....

Code: (Select All)
    DO
        LIMIT LIMITRATE
        CLS
        PUTIMAGE (0, 0), BGImage
        MENUMAKER Menu()
        SELECT CASE Pointer
            CASE 0: PUTIMAGE (MenuPos(2).X1 - 50, MenuPos(2).Y1 + 10), CheckSelect
            CASE 1: PUTIMAGE (MenuPos(3).X1 - 50, MenuPos(3).Y1 + 10), CheckSelect
            CASE 2: PUTIMAGE (MenuPos(4).X1 - 50, MenuPos(4).Y1 + 10), CheckSelect
            CASE 3: PUTIMAGE (MenuPos(5).X1 - 50, MenuPos(5).Y1 + 10), CheckSelect
        END SELECT
        DISPLAY
        IF SelectFlag THEN PAUSE TIME 'Avoid double press delay
        SelectFlag = FALSE 'reset input

        'Checking for key press (keyboard)
        IF KEYDOWN(CVI(CHR$(0) + "H")) THEN ' up case
            IF Pointer = 0 THEN Pointer = 3 ELSE Pointer = Pointer - 1
            SelectFlag = TRUE
        END IF
        IF KEYDOWN(CVI(CHR$(0) + "P")) THEN 'down case
            IF Pointer = 3 THEN Pointer = 0 ELSE Pointer = Pointer + 1
            SelectFlag = TRUE
        END IF

        'Checking for mouse input
        MOUSE "Poll"
        MOUSE "Release"
        MOUSE "Action"
        MOUSE "Loop"
    LOOP UNTIL KEYDOWN(13) OR KEYDOWN(32) OR MFlag 'Return/space bar/mouse click to select


[Image: image.png]
(Using almost 3 times as Chrome after a few mins...)

It seems to only happen on Menu selection screens. The leak appears in all V4 releases from me but V3 does not have the leak. Any thoughts what it may be?

If any additional code is needed or anything else of the sort, please let me know!!
Reply
#2
Need to see what's going on in MENUMAKER()
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#3
My guess would be one of those images is being endlessly recreated inside a sub, without a FREEIMAGE releasing that image.
Reply
#4
Code: (Select All)
SUB MENUMAKER (Elements() AS STRING)
    DIM AS INTEGER StartX, StartY, Count

    FONT LOADFONT("script.ttf", 96)
    StartX = 640 - QPrintWidth(Elements(1)) / 2: StartY = 75: Count = 2
    QPrintString StartX, StartY, Elements(1)
    LINE (640 - QPrintWidth(Elements(1)) / 2, StartY + QFontHeight - 18)-(640 + QPrintWidth(Elements(1)) / 2, StartY + QFontHeight - 22), , BF
    StartY = StartY + QFontHeight + 15
    FONT LOADFONT("script.ttf", 72)
    DO WHILE Elements(Count) <> "*"
        StartX = 640 - QPrintWidth(Elements(Count)) / 2
        QPrintString StartX, StartY, Elements(Count)
        MenuPos(Count).X1 = StartX
        MenuPos(Count).Y1 = StartY
        MenuPos(Count).X2 = StartX + QPrintWidth(Elements(Count))
        MenuPos(Count).Y2 = StartY + QFontHeight
        StartY = StartY + QFontHeight
        Count = Count + 1
    LOOP
    MenuPos(Count).X1 = -1 'Flag for the mouse routinue to stop producing boundary boxes for the checkmark to jump to.
END SUB

Looking at this, guess my eyes didn't even think this could be the issue but reloading the same font over and over is it, perhaps?
Reply
#5
Yep.  Anything you load, you need to free, particularly when dealing with it being inside a looping structure.

I'd suggest just loading the font once at program initialization and then keeping it in memory as a shared variable.  Then you can just _FONT shared_variable_name as needed, without having to reload that font over and over in memory.
Reply
#6
(05-10-2023, 02:27 AM)NasaCow Wrote: Never noticed it before but my menu selection screens have a memory leak! It keeps adding about 8MB/s of system memory. It is a pretty forward loop and the MOUSE calls are not the source (they were all commented out when I was trying to locate the source of the leak). I am really at a loss here....

Code: (Select All)
    DO
        LIMIT LIMITRATE
        CLS
        PUTIMAGE (0, 0), BGImage
        MENUMAKER Menu()
        SELECT CASE Pointer
            CASE 0: PUTIMAGE (MenuPos(2).X1 - 50, MenuPos(2).Y1 + 10), CheckSelect
            CASE 1: PUTIMAGE (MenuPos(3).X1 - 50, MenuPos(3).Y1 + 10), CheckSelect
            CASE 2: PUTIMAGE (MenuPos(4).X1 - 50, MenuPos(4).Y1 + 10), CheckSelect
            CASE 3: PUTIMAGE (MenuPos(5).X1 - 50, MenuPos(5).Y1 + 10), CheckSelect
        END SELECT
        DISPLAY
        IF SelectFlag THEN PAUSE TIME 'Avoid double press delay
        SelectFlag = FALSE 'reset input

        'Checking for key press (keyboard)
        IF KEYDOWN(CVI(CHR$(0) + "H")) THEN ' up case
            IF Pointer = 0 THEN Pointer = 3 ELSE Pointer = Pointer - 1
            SelectFlag = TRUE
        END IF
        IF KEYDOWN(CVI(CHR$(0) + "P")) THEN 'down case
            IF Pointer = 3 THEN Pointer = 0 ELSE Pointer = Pointer + 1
            SelectFlag = TRUE
        END IF

        'Checking for mouse input
        MOUSE "Poll"
        MOUSE "Release"
        MOUSE "Action"
        MOUSE "Loop"
    LOOP UNTIL KEYDOWN(13) OR KEYDOWN(32) OR MFlag 'Return/space bar/mouse click to select


[Image: image.png]
(Using almost 3 times as Chrome after a few mins...)

It seems to only happen on Menu selection screens. The leak appears in all V4 releases from me but V3 does not have the leak. Any thoughts what it may be?

If any additional code is needed or anything else of the sort, please let me know!!


I would like to see your mouse code. I am trying to add it to my game, but I am having a lot of problems Sad
10 PRINT "Hola! Smile"
20 GOTO 10
Reply
#7
Hi @Ikerkaz

(05-10-2023, 11:12 AM)Ikerkaz Wrote: I would like to see your mouse code. I am trying to add it to my game, but I am having a lot of problems Sad

I will bet real money you might gain some helpful tips from Terry's Tutorial. I even looked up the chapter to check out:
https://www.qb64tutorial.com/lesson7

Something to do whilst we wait for reply from NasaCow.
b = b + ...
Reply
#8
(05-10-2023, 01:27 PM)bplus Wrote: Hi @Ikerkaz

(05-10-2023, 11:12 AM)Ikerkaz Wrote: I would like to see your mouse code. I am trying to add it to my game, but I am having a lot of problems Sad

I will bet real money you might gain some helpful tips from Terry's Tutorial. I even looked up the chapter to check out:
https://www.qb64tutorial.com/lesson7

Something to do whilst we wait for reply from NasaCow.

Ok thank you very much!!! I will read it Smile
10 PRINT "Hola! Smile"
20 GOTO 10
Reply
#9
(05-10-2023, 02:35 PM)Ikerkaz Wrote:
(05-10-2023, 01:27 PM)bplus Wrote: Hi @Ikerkaz

(05-10-2023, 11:12 AM)Ikerkaz Wrote: I would like to see your mouse code. I am trying to add it to my game, but I am having a lot of problems Sad

I will bet real money you might gain some helpful tips from Terry's Tutorial. I even looked up the chapter to check out:
https://www.qb64tutorial.com/lesson7

Something to do whilst we wait for reply from NasaCow.

Ok thank you very much!!! I will read it Smile

Good Smile
b = b + ...
Reply
#10
(05-10-2023, 05:13 AM)SMcNeill Wrote: Yep.  Anything you load, you need to free, particularly when dealing with it being inside a looping structure.

I'd suggest just loading the font once at program initialization and then keeping it in memory as a shared variable.  Then you can just _FONT shared_variable_name as needed, without having to reload that font over and over in memory.

Exactly what I did and it solved the problem. Stablized at 73.7 MBs. Still the biggest program I ever wrote but only 10% as greedy as chrome  Big Grin

(05-10-2023, 11:12 AM)Ikerkaz Wrote:
(05-10-2023, 02:27 AM)NasaCow Wrote: Never noticed it before but my menu selection screens have a memory leak! It keeps adding about 8MB/s of system memory. It is a pretty forward loop and the MOUSE calls are not the source (they were all commented out when I was trying to locate the source of the leak). I am really at a loss here....

Code: (Select All)
    DO
        LIMIT LIMITRATE
        CLS
        PUTIMAGE (0, 0), BGImage
        MENUMAKER Menu()
        SELECT CASE Pointer
            CASE 0: PUTIMAGE (MenuPos(2).X1 - 50, MenuPos(2).Y1 + 10), CheckSelect
            CASE 1: PUTIMAGE (MenuPos(3).X1 - 50, MenuPos(3).Y1 + 10), CheckSelect
            CASE 2: PUTIMAGE (MenuPos(4).X1 - 50, MenuPos(4).Y1 + 10), CheckSelect
            CASE 3: PUTIMAGE (MenuPos(5).X1 - 50, MenuPos(5).Y1 + 10), CheckSelect
        END SELECT
        DISPLAY
        IF SelectFlag THEN PAUSE TIME 'Avoid double press delay
        SelectFlag = FALSE 'reset input

        'Checking for key press (keyboard)
        IF KEYDOWN(CVI(CHR$(0) + "H")) THEN ' up case
            IF Pointer = 0 THEN Pointer = 3 ELSE Pointer = Pointer - 1
            SelectFlag = TRUE
        END IF
        IF KEYDOWN(CVI(CHR$(0) + "P")) THEN 'down case
            IF Pointer = 3 THEN Pointer = 0 ELSE Pointer = Pointer + 1
            SelectFlag = TRUE
        END IF

        'Checking for mouse input
        MOUSE "Poll"
        MOUSE "Release"
        MOUSE "Action"
        MOUSE "Loop"
    LOOP UNTIL KEYDOWN(13) OR KEYDOWN(32) OR MFlag 'Return/space bar/mouse click to select


[Image: image.png]
(Using almost 3 times as Chrome after a few mins...)

It seems to only happen on Menu selection screens. The leak appears in all V4 releases from me but V3 does not have the leak. Any thoughts what it may be?

If any additional code is needed or anything else of the sort, please let me know!!


I would like to see your mouse code. I am trying to add it to my game, but I am having a lot of problems Sad
 
My mouse code is not anything special. You can ignore action since I used it to automate drawing boxes for my menus but you can take a look at it for ideas. My general mouse cycle is establishing an array with UDT and hiighlighting it temporarly wit LINE (x1,y1)-(x2,y2),,B so I can see my mouse boxes. Once I am happy with the size and locations, I remove the line.

Best to start small and play with the mouse before trying to use it in a program! Good luck  Cool 

 Simple but does my box creation easily.
Code: (Select All)
'Used to help establish boxes for the mouse
TYPE MenuPosType
    X1 AS INTEGER
    Y1 AS INTEGER
    X2 AS INTEGER
    Y2 AS INTEGER
END TYPE

These are the general mouse items I track
Code: (Select All)
'Global mouse status
TYPE MouseType
    X AS INTEGER 'Current X position
    Y AS INTEGER 'Current Y position
    OldX AS INTEGER 'Prior X position
    OldY AS INTEGER 'Prior Y position
    LBut AS INTEGER 'Left button current state
    RBut AS INTEGER 'Right button current state
    Pointer AS INTEGER 'Mouse "pointing at what" when clicked - Not while held
END TYPE

My general loop code. Action needs to be changed to fit what you are doing, if you have something repeative.
Code: (Select All)
'Mouse updating
SUB MOUSE (Status AS STRING)
    STATIC AS BIT LB, RB, LButHeld, RButHeld
    DIM AS INTEGER Count

    SELECT CASE Status:
        'Run at the begining before entering a DO/LOOP
        CASE "Inital":
            LB = FALSE: M.LBut = 0: LButHeld = FALSE: MLButAct = FALSE
            RB = FALSE: M.RBut = 0: RButHeld = FALSE: MRButAct = FALSE
            MFlag = FALSE: M.X = 0: M.Y = 0: M.OldX = 0: M.OldY = 0: M.Pointer = -1

            'Current state of the mouse
        CASE "Poll"
            WHILE MOUSEINPUT: WEND
            M.X = MOUSEX
            M.Y = MOUSEY
            M.LBut = MOUSEBUTTON(1)
            M.RBut = MOUSEBUTTON(2)

            'Left click
        CASE "Click":
            IF M.LBut THEN MLButAct = TRUE

            'Right click
        CASE "R_Click:"
            IF M.RBut THEN MRButAct = TRUE

            'This detects when left mouse button is released - programmer's choice to use click or release as trigger
        CASE "Release":
            IF M.LBut THEN '1) Button is down we need to see if it is still down
                IF NOT LB THEN '2) Record that the button is down and then empty loop while held
                    LB = TRUE
                END IF
            ELSE
                IF LB THEN '4) Once the mouse has been released and been pressed before
                    IF LButHeld THEN MLButAct = TRUE '5) Process the action with a true flag
                    LB = FALSE: LButHeld = FALSE '6) Reset the button to up and button being held
                END IF
            END IF
            IF LB AND NOT LButHeld THEN LButHeld = TRUE '3) If the button is pressed and record the holding state

            'This detects when right mouse button is released - programmer's choice to use click or release as trigger
        CASE "R-Release":
            IF M.RBut THEN '1) Button is down we need to see if it is still down
                IF NOT RB THEN '2) Record that the button is down and then empty loop while held
                    RB = TRUE
                END IF
            ELSE
                IF RB THEN '4) Once the mouse has been released and been pressed before
                    IF RButHeld THEN MRButAct = TRUE '5) Process the action with a true flag
                    RB = FALSE: RButHeld = FALSE '6) Reset the button to up and button being held
                END IF
            END IF
            IF RB AND NOT RButHeld THEN RButHeld = TRUE '3) If the button is pressed and record the holding state

            'Needs to be called after all mouse checking is finished and before the end of the loop
        CASE "Loop":
            M.OldX = M.X: M.OldY = M.Y
            MLButAct = FALSE
            MRButAct = FALSE

            '--This is used to process my menu screens, you will want to make your own for repeative DO/LOOPs, if you have them--
            'Positions start at index 2 (Title of the screen is index 1, not tracked)
        CASE "Action":
            Count = 2
            IF M.X <> M.OldX AND M.Y <> M.OldY OR MLButAct THEN 'Check if our mouse is moving or a button is being held
                DO WHILE MenuPos(Count).X1 <> -1
                    IF M.X > MenuPos(Count).X1 AND M.X < MenuPos(Count).X2 AND M.Y > MenuPos(Count).Y1 AND M.Y < MenuPos(Count).Y2 THEN M.Pointer = Count - 2: Pointer = Count - 2
                    Count = Count + 1
                LOOP
                IF MLButAct THEN 'Once the mouse is released, are we stil over the same box? If so then MFlag is true and we can exit the loop using M.pointer as our pointer of the mouse
                    Count = 2
                    DO WHILE MenuPos(Count).X1 <> -1
                        IF M.X > MenuPos(Count).X1 AND M.X < MenuPos(Count).X2 AND M.Y > MenuPos(Count).Y1 AND M.Y < MenuPos(Count).Y2 AND M.Pointer = Count - 2 THEN MFlag = TRUE
                        Count = Count + 1
                    LOOP
                END IF
            END IF

            'Debugging in case of mistype
        CASE ELSE: PRINT "Keyword: " + Status + " is not valid": SLEEP: SYSTEM

    END SELECT
END SUB

If you need any help, don't be afraid to ask!
Reply




Users browsing this thread: 2 Guest(s)