Thread Tools Display Modes
02-14-12, 03:34 PM   #1
laukond
A Black Drake
Join Date: Dec 2011
Posts: 87
Unstable Memory Usage

What causes unstable memory usage?
If I /run collectgarbage() the memory halved!

PS: here it is if you care to look, but I warn you it's very long and cluttery.
http://pastebin.com/ygj4zqcj

Have a good day.

Edit: I have split the AddOn into multiple AddOns to locate the sinners . Here are two links to the unstable AddOns:
* http://pastebin.com/wKVjaK0g
* http://pastebin.com/3KmAtVXE

Last edited by laukond : 02-15-12 at 12:49 PM.
  Reply With Quote
02-14-12, 03:38 PM   #2
Waky
A Cobalt Mageweaver
 
Waky's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2010
Posts: 200
Just looking quickly, I'd say that this part of your code is generating a lot of garbage every time you call it:

Code:
if (KeybindsHide == 1) then
for i=1,12 do _G["ActionButton"..i.."HotKey"]:SetAlpha(0)end;for i=1,12 do
_G["MultiBarBottomRightButton"..i.."HotKey"]:SetAlpha(0)end;for i=1,12 do
_G["MultiBarBottomLeftButton"..i.."HotKey"]:SetAlpha(0)end; for i=1,12 do
_G["MultiBarRightButton"..i.."HotKey"]:SetAlpha(0)end; for i=1,12 do
_G["MultiBarLeftButton"..i.."HotKey"]:SetAlpha(0)end; for i=1,12 do
_G["BonusActionButton"..i.."HotKey"]:SetAlpha(0)end;
end
 
if (MacroTextHide == 1) then
for i=1,12 do _G["ActionButton"..i.."Name"]:SetAlpha(0)end;for i=1,12 do
_G["MultiBarBottomRightButton"..i.."Name"]:SetAlpha(0)end;for i=1,12 do
_G["MultiBarBottomLeftButton"..i.."Name"]:SetAlpha(0)end; for i=1,12 do
_G["MultiBarRightButton"..i.."Name"]:SetAlpha(0)end; for i=1,12 do
_G["MultiBarLeftButton"..i.."Name"]:SetAlpha(0)end; for i=1,12 do
_G["BonusActionButton"..i.."Name"]:SetAlpha(0)end;
end
Every time this is called it finds 144 frames then throws away their name. You might want to just do it once and store all of the frames in a table, then iterate over that table every time.

Looking a little farther down, it seems this is how you call most of your _G frames. Like I said before, I'd save them once then use the saved value so you don't generate garbage every time you call the function.
  Reply With Quote
02-14-12, 03:40 PM   #3
laukond
A Black Drake
Join Date: Dec 2011
Posts: 87
Thank you very much for the quick reply :-)
Could you just link an example of you you would do it? Just the frame of it so I know what you mean, afterall I am new to Lua.
  Reply With Quote
02-14-12, 03:51 PM   #4
Waky
A Cobalt Mageweaver
 
Waky's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2010
Posts: 200
This is just an example for one of the buttons:

Code:
local actionButtonHotkey= {}
-- Just creating a blank table for just ActionButtonHotKey's

for i=1,12 do
   actionButtonHotkey[i] = _G[format("ActionButton%dHotKey",i)];
end
-- Iterate over 1 through 12 and store all of these frames into the blank table we created earlier
The above should only be ran once, as to fill up the table

The following would be what you do to for your :SetAlpha(0) function:

Code:
for k,v in pairs(actionButtonHotkey) do
   v:SetAlpha(0);
end
This way it would just go over the table every time and just reuse the previously saved frame
  Reply With Quote
02-14-12, 04:10 PM   #5
laukond
A Black Drake
Join Date: Dec 2011
Posts: 87
Playing with a thought here, but I'm not sure which word to use by the "elseif" (line 11), the hotkey hiding works, but the macro part doesn't.

LUA Code:
  1. local macrohide = 1
  2. local hotkeyhide = 1
  3.  
  4. local actionButtonHotkey = {}
  5. -- Just creating a blank table for just ActionButtonHotKeys
  6.  
  7. if (hotkeyhide == 1) then
  8.     for i=1,12 do
  9.     actionButtonHotkey[i] = _G[format("ActionButton%dHotKey",i)];
  10.     end
  11.         elseif (macrohide == 1) then
  12.         for i=1,12 do
  13.         actionButtonHotkey[i] = _G[format("ActionButton%dName",i)];
  14.     end
  15. end
  16.  
  17. -- Iterate over 1 through 12 and store all of these frames into the blank table we created earlier
  18.  
  19. for k,v in pairs(actionButtonHotkey) do
  20.    v:SetAlpha(0);
  21. end

Bonus question off-topic: Which program do you use for writing such code?
  Reply With Quote
02-14-12, 04:15 PM   #6
Waky
A Cobalt Mageweaver
 
Waky's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2010
Posts: 200
The elseif syntax will make it so the second part of the code will only run if the previous if condition wasn't met.

So say you have
x = 5;
y = 10;

then you have such code:

Code:
if (x==5) then
   print("x was 5");
elseif (y==10) then
   print("y was 10");
end
Even though the second if "(y==10)" was true the code was never reached since the first if statement was met when x equaled 5. The code would then print "x was 5" and then stop in that condition.

From what I understand you're trying to do 2 if statements like such:

Code:
if (hotkeyhide == 1) then
    for i=1,12 do
         actionButtonHotkey[i] = _G[format("ActionButton%dHotKey",i)]; 
    end
end
if (macrohide == 1) then
    for i=1,12 do
        actionButtonHotkey[i] = _G[format("ActionButton%dName",i)];
    end
end
  Reply With Quote
02-14-12, 08:27 PM   #7
Saiket
A Chromatic Dragonspawn
 
Saiket's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 154
Usually the biggest contributor to increasing memory is temporary table creation. There are three places in your code that create tables each time they run:
  1. Line 697:
    lua Code:
    1. local TabZone = {
    2.                 ["pvp"] = true,
    3.                 ["arena"] = true,
    4.         }
  2. Line 724:
    lua Code:
    1. local TabZone = {
    2.                 ["pvp"] = true,
    3.                 ["arena"] = true,
    4.         }
  3. Line 1221:
    lua Code:
    1. table.insert(AddOnData,{GetAddOnInfo(i),mem});
Since the first two tables never change and are identical, you could create one copy of the table before defining tabChanger:ZONE_CHANGED_NEW_AREA and MinimapHide:ZONE_CHANGED_NEW_AREA. That way they'll use the one copy each time they're called as opposed to creating new copies of it every time you change zones.

The third table is probably what causes lots of garbage memory though, since it creates a new table for each addon every time it runs. There are a number of ways to fix it, but I suggest reading this Wowpedia article on avoiding garbage tables.
  Reply With Quote
02-15-12, 10:29 AM   #8
laukond
A Black Drake
Join Date: Dec 2011
Posts: 87
Originally Posted by Waky View Post
This is just an example for one of the buttons
How would I apply this to all the bars?
  Reply With Quote
02-15-12, 12:49 PM   #9
laukond
A Black Drake
Join Date: Dec 2011
Posts: 87
Edit: I have split the AddOn into multiple AddOns to locate the sinners . Here are two links to the unstable AddOns:
* http://pastebin.com/wKVjaK0g
* http://pastebin.com/3KmAtVXE
  Reply With Quote
02-15-12, 02:08 PM   #10
laukond
A Black Drake
Join Date: Dec 2011
Posts: 87
Originally Posted by Saiket View Post
There are a number of ways to fix it.
Thank you for your reply . I read the but I did not understand most of it, since I am quite new to Lua .
Would you mind coding me a solution to it?
  Reply With Quote
02-15-12, 02:57 PM   #11
Saiket
A Chromatic Dragonspawn
 
Saiket's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 154
Originally Posted by laukond View Post
Thank you for your reply . I read the but I did not understand most of it, since I am quite new to Lua .
Would you mind coding me a solution to it?
You're storing a two-dimensional array of addon data with one table per addon, each with two elements in it. You could store the same data using only two recycled tables instead, each with one element per addon. The sort function would have to change slightly, but you'll only ever create two tables this way:
lua Code:
  1. local AddOnMemory, Order={}, {};
  2. local function SortByMemory(addon1,addon2)
  3.     return AddOnMemory[addon1]<AddOnMemory[addon2]
  4. end

And then in MainMenuBarPerformanceBarFrame_OnEnter:
lua Code:
  1. --[[    Custom Code ]]
  2. --  Replace memory code with our own
  3.     UpdateAddOnMemoryUsage();
  4.     table.wipe(AddOnMemory);
  5.     table.wipe(Order);
  6.     local total=0;
  7.  
  8.     for i=1,GetNumAddOns() do
  9.         AddOnMemory[i]=GetAddOnMemoryUsage(i);
  10.         Order[i]=i;
  11.         total=total+AddOnMemory[i];
  12.     end
  13.     table.sort(Order,SortByMemory);
  14.  
  15.     if total>0 then
  16.         GameTooltip:AddLine(" ");
  17.         if total>1000 then
  18.             AddNewbieTip(GameTooltip,TOTAL_MEM_MB_ABBR:format(total/1000),1,1,1,NEWBIE_TOOLTIP_MEMORY);
  19.         else
  20.             AddNewbieTip(GameTooltip,TOTAL_MEM_KB_ABBR:format(total),1,1,1,NEWBIE_TOOLTIP_MEMORY);
  21.         end
  22.  
  23.         for i,addon in ipairs(Order) do
  24.             local mem,name=AddOnMemory[addon],GetAddOnInfo(addon)
  25.             if mem>0 then
  26.                 if mem>1000 then
  27.                     GameTooltip:AddLine(ADDON_MEM_MB_ABBR:format(mem/1000,name),1,1,1);
  28.                 else
  29.                     GameTooltip:AddLine(ADDON_MEM_KB_ABBR:format(mem,name),1,1,1);
  30.                 end
  31.             end
  32.             if i>=MaxListSize then break; end
  33.         end
  34.     end
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Unstable Memory Usage


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off