Memory Leak - NasaCow - 05-10-2023
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
(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!!
RE: Memory Leak - TerryRitchie - 05-10-2023
Need to see what's going on in MENUMAKER()
RE: Memory Leak - SMcNeill - 05-10-2023
My guess would be one of those images is being endlessly recreated inside a sub, without a FREEIMAGE releasing that image.
RE: Memory Leak - NasaCow - 05-10-2023
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?
RE: Memory Leak - SMcNeill - 05-10-2023
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.
RE: Memory Leak - Ikerkaz - 05-10-2023
(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
(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
RE: Memory Leak - bplus - 05-10-2023
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
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.
RE: Memory Leak - Ikerkaz - 05-10-2023
(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
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
RE: Memory Leak - bplus - 05-10-2023
(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
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
Good
RE: Memory Leak - NasaCow - 05-11-2023
(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
(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
(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
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
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!
|