WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Frame:Show() increases memory usage on each toggle? (https://www.wowinterface.com/forums/showthread.php?t=57333)

Lybrial 08-08-19 12:27 AM

Frame:Show() increases memory usage on each toggle?
 
Hi Guys,

I wanted to implement a grid toggle, I started with the vertical lines and tried it out.
Here the code, it is quite simple:

Lua Code:
  1. LybrialAnchors = LybrialUI:NewModule("Lybrial Anchors");
  2.  
  3. local LybrialAnchors = LybrialAnchors;
  4.  
  5. LybrialAnchors.grid = nil;
  6.  
  7. -- Initialize Addon
  8. function LybrialAnchors:OnInitialize()
  9. end
  10.  
  11. -- Get Options
  12. function LybrialAnchors:GetOptions()
  13.     return {
  14.         toggleGrid = {
  15.             type = "toggle",
  16.             order = 1,
  17.             name = "Toggle Grid",
  18.             set = function(_, value)
  19.                 self:ToggleGrid(value);
  20.             end,
  21.             width = "full"
  22.         },
  23.     };
  24. end
  25.  
  26. function LybrialAnchors:ToggleGrid(toggle)
  27.     if (toggle) then
  28.         if (not self.grid) then
  29.             print("Create Grid");
  30.  
  31.             self:CreateGrid();
  32.         else
  33.             print("Show Grid");
  34.  
  35.             self.grid:Show();
  36.         end
  37.     else
  38.         print("Hide Grid");
  39.  
  40.         self.grid:Hide();
  41.     end
  42. end
  43.  
  44. function LybrialAnchors:CreateGrid()
  45.     if (not self.grid) then
  46.         self.grid = CreateFrame("Frame", "Grid", UIParent);
  47.         self.grid:SetFrameStrata("BACKGROUND");
  48.     end
  49.  
  50.     local steps = 128;
  51.     local width, height = UIParent:GetSize();
  52.     local widthStep = (width / steps);
  53.  
  54.     self.grid:SetPoint("CENTER", UIParent);
  55.     self.grid:SetSize(width, height);
  56.     self.grid:Show();
  57.  
  58.     self:CreateVerticalLines(steps, widthStep);
  59. end
  60.  
  61. function LybrialAnchors:CreateVerticalLines(steps, widthStep)
  62.     for i = 0, steps do
  63.         local region = self.grid:CreateTexture();
  64.         region:SetColorTexture(0, 0, 0);
  65.         region:SetDrawLayer("BACKGROUND", 0);
  66.         region:ClearAllPoints();
  67.         region:SetPoint("TOPLEFT", self.grid, "TOPLEFT", (i * widthStep), 0);
  68.         region:SetPoint("BOTTOMRIGHT", self.grid, "BOTTOMLEFT", (i * widthStep), 0);
  69.     end
  70. end

Let me click the toggle input 5 times. The output is:

Code:

Create Grid
Hide Grid
Show Grid
Hide Grid
Show Grid

So as you can see the first time I enable the toggle the grid is getting created. After that the grid frame
is only showing or hiding. So it should work exactly as I want it to work.

But the problem is: On each `self.grid:Show()` the memory usage of my addon is increasing.
I toggled 50 times and my addon memory usage was increased by 25 MB.

I dont understand why a `Show()` on an already existing `Frame` is increasing memory usage.
Anything anyone can tell me about that?

Rilgamon 08-08-19 01:50 AM

In GetOptions you create a new array and a new function everytime.
So for every refresh of your options panel you see an increase in memory usage.
Most of it should be returned when garbage collect is run.

Lybrial 08-08-19 01:59 AM

Hi,

and with "refresh" you mean that when I click the toggle input the whole thing gets refreshed?
From my understanding the options panel is created only once when the addon is getting initialized.
I mean thats the whole thing behind Ace options and Ace config dialogue.

Rilgamon 08-08-19 02:07 AM

Not sure 100% but add a print to your function and see how often its called ... esp when a value is changed.

Lybrial 08-08-19 02:12 AM

Quote:

Originally Posted by Rilgamon (Post 333075)
Not sure 100% but add a print to your function and see how often its called ... esp when a value is changed.

Lua Code:
  1. function LybrialAnchors:GetOptions()
  2.     print("get options");
  3.  
  4.     return {
  5.         toggleGrid = {
  6.             type = "toggle",
  7.             order = 1,
  8.             name = "Toggle Grid",
  9.             set = function(_, value)
  10.                 print("value changed: ", value);
  11.  
  12.                 self:ToggleGrid(value);
  13.             end,
  14.             width = "full"
  15.         },
  16.     };
  17. end

Code:

get options
value changed: true
Create Grid
value changed: false
Hide Grid
value changed: true
Show Grid
value changed: false
Hide Grid
value changed: true
Show Grid

Seems to be fine.

Rilgamon 08-08-19 02:18 AM

true, now you know the "problem" is not in the displayed code.

Lybrial 08-08-19 04:13 AM

Quote:

Originally Posted by Rilgamon (Post 333077)
true, now you know the "problem" is not in the displayed code.

The displayed code is the only code. I removed / disabled anything else to find the root of that issue.

Vrul 08-08-19 06:19 AM

Quote:

Originally Posted by Lybrial (Post 333072)
Lua Code:
  1. function LybrialAnchors:CreateVerticalLines(steps, widthStep)
  2.     for i = 0, steps do
  3.         local region = self.grid:CreateTexture();
  4.         region:SetColorTexture(0, 0, 0);
  5.         region:SetDrawLayer("BACKGROUND", 0);
  6.         region:ClearAllPoints();
  7.         region:SetPoint("TOPLEFT", self.grid, "TOPLEFT", (i * widthStep), 0);
  8.         region:SetPoint("BOTTOMRIGHT", self.grid, "BOTTOMLEFT", (i * widthStep), 0);
  9.     end
  10. end

You are creating new vertical lines each time that code is called. Currently they are all stacked on top of each other so you can't tell but if you change steps or widthStep you will be able to tell.

You need to reuse lines or create new ones as needed and hide the ones that are not in use if you end up with extras. You can see an example of this in GraphPaper (note: versions 1.4.10 and prior use CreateTexture as you are using here and version 1.4.11 uses the newer CreateLine).

Lybrial 08-08-19 07:56 AM

How should this create new vertical lines over and over again when it is only called once?

Vrul 08-08-19 08:41 AM

Quote:

Originally Posted by Lybrial (Post 333081)
How should this create new vertical lines over and over again when it is only called once?

My mistake. I only looked at the last two functions and saw you checking if the grid already existed but not the lines.

Lybrial 08-08-19 08:58 AM

Quote:

Originally Posted by Vrul (Post 333082)
My mistake. I only looked at the last two functions and saw you checking if the grid already existed but not the lines.

Dont worry. This would be the very obvious memory killer :)

Rilgamon 08-08-19 09:38 AM

Like I said, the "problem" is probably somewere else...ace3?

Lybrial 08-08-19 10:14 AM

Quote:

Originally Posted by Rilgamon (Post 333084)
Like I said, the "problem" is probably somewere else...ace3?

Holy moly. I was wrong. I tried the prints in `GetOptions` again. I dont know
what I did before but now it prints it everytime when I do something, like clicking
the toggle button:

Code:

get options
value changed: true
Create Grid
get options
value changed: false
Hide Grid
get options
value changed: true
Show Grid
get options
value changed: false
Hide Grid
get options
value changed: true
Show Grid

Seems like to be the expected behaviour. Garbage collector cleans it up. But still a bit annoying.

Rilgamon 08-08-19 11:47 AM

Cool, so just create the table and function once outside :)

Lybrial 08-08-19 11:56 AM

Quote:

Originally Posted by Rilgamon (Post 333087)
Cool, so just create the table and function once outside :)

Yep, this I will do. Thank you, you were right from the very beginning ;)

Rilgamon 08-08-19 12:18 PM

No, I just had a guess ;) I'm never sure when it comes to the tables of ace3 ... there is so much "magic" in this :P


All times are GMT -6. The time now is 04:23 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI