Thread Tools Display Modes
01-29-10, 09:50 PM   #1
alimjocox
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Oct 2009
Posts: 96
mem usage

I'm trying to write a few small short addons, but i was wondering what in the lua code determines its memory usage in game.

i tried testing by making two identical addons just approached differently and one was using more memory than the other.

not sure if i worded this properly or if it has an easy answer but thx in advance for help
  Reply With Quote
01-29-10, 10:25 PM   #2
Katae
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Jun 2007
Posts: 208
Short answer: Table creation and function closures are the main causes.

Long answer:
http://www.lua.org/gems/sample.pdf (PDF)
http://www.wowwiki.com/Lua_object_memory_sizes

Last edited by Katae : 01-29-10 at 10:30 PM.
  Reply With Quote
01-29-10, 10:34 PM   #3
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
Memory usage is most of the time temporary.
The more variables you fill, the more space is used.

For example many addons have an onupdate-script

Code:
local function mytimer(self, elapsed)
  local a
  local b
  [...]
end
This script is called everytime when the frame is redrawn.
Many times per second. This creates many local a and b
variables. Depending on the stuff stored this can grow big
quite fast. Garbage collection needs time to find your a and b vars
are no longer needed. Perhaps it could make sense to move the local vars
to the parent scope.

Code:
local a
local b
local function mytimer(self, elapsed)
  [...]
end
If you want to see a realworld example check out Buttonfacade.
Run it in a raid and you can see memory usage go up to 40MB.
Most of the memory is freed on gc, but it takes a lot of time.
If you rewrite a few functions memory usage goes down to 3MB ... but cpu time goes up.

Structures like

Code:
local LBFGroup = LBF:Group(addon)
[...]
arg = LBFGroup,
[...]
can be less memory hungry when you change it to

Code:
[...]
arg =  LBF:Group(addon),
[...]
Depending on how often a local reference is used this trades memory for
cpu cycles ... modern computers have lots of memory but cpu cycles are
still way too few

Not sure if this helps ... I'm still a beginner in lua
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
01-30-10, 01:13 AM   #4
Amenity
Guest
Posts: n/a
Originally Posted by Rilgamon View Post
If you want to see a realworld example check out Buttonfacade.
Run it in a raid and you can see memory usage go up to 40MB.
Most of the memory is freed on gc, but it takes a lot of time.
If you rewrite a few functions memory usage goes down to 3MB ... but cpu time goes up.
And just to point out (since everyone seems memory-crazed these days), 40MB is nothing for today's computers. You can't even fit a Britney Spears CD in 40MB without dumping data. As I'm sitting here typing this, Firefox is using four times as much memory uploading pictures of my kids. All total, my computer uses about 2.3GB of RAM just sitting here (granted, I'm not frugal with my memory use since I've got a metric crapton of it).

My point is...don't worry about memory use. You probably see more detriment to game performance by simply having a desktop wallpaper than you do from addon memory. Playing in Windowed mode is another sure-fire way to annihilate your framerates (unless you've got some top-notch gear...and even then, windowed mode won't allow CrossfireX or SLi). There's probably a million other things you do every single day that kill your performance more.
  Reply With Quote
01-31-10, 05:18 AM   #5
alimjocox
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Oct 2009
Posts: 96
so what would be better? on something that will appear often

Code:
backdrop = { 
	  bgFile = BLANK_TEXTURE, 
	  edgeFile = BLANK_TEXTURE, 
	  edgeSize = 1, 
	  insets = { left = -1, right = -1, top = -1, bottom = -1 }
}
Code:
function simpleBackdrop(frameName)
frameName:SetBackdrop({ 
	  bgFile = BLANK_TEXTURE,
	  edgeFile = BLANK_TEXTURE, 
	  edgeSize = 1, 
	  insets = { left = -1, right = -1, top = -1, bottom = -1 }
})
return frameName
end
using f:SetBackdrop(backdrop) or simpleBackdrop(f) or would be it better to just repeat bgFile ...... on every occurrence ??

i dont know if it matters (logic says it does matter[not a programmer]) but this will be in a seperate .lua file to everything else.
  Reply With Quote
01-31-10, 07:07 AM   #6
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Before comparing memory usage make sure to run this macro:
Code:
/run collectgarbage("collect")
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
01-31-10, 07:46 AM   #7
Cladhaire
Salad!
 
Cladhaire's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Jul 2005
Posts: 1,935
Originally Posted by Rilgamon View Post
Memory usage is most of the time temporary.
The more variables you fill, the more space is used.

For example many addons have an onupdate-script

Code:
local function mytimer(self, elapsed)
  local a
  local b
  [...]
end
This script is called everytime when the frame is redrawn.
Many times per second. This creates many local a and b
variables. Depending on the stuff stored this can grow big
quite fast. Garbage collection needs time to find your a and b vars
are no longer needed. Perhaps it could make sense to move the local vars
to the parent scope.

Code:
local a
local b
local function mytimer(self, elapsed)
  [...]
end
If you want to see a realworld example check out Buttonfacade.
Run it in a raid and you can see memory usage go up to 40MB.
Most of the memory is freed on gc, but it takes a lot of time.
If you rewrite a few functions memory usage goes down to 3MB ... but cpu time goes up.

Structures like

Code:
local LBFGroup = LBF:Group(addon)
[...]
arg = LBFGroup,
[...]
can be less memory hungry when you change it to

Code:
[...]
arg =  LBF:Group(addon),
[...]
Depending on how often a local reference is used this trades memory for
cpu cycles ... modern computers have lots of memory but cpu cycles are
still way too few

Not sure if this helps ... I'm still a beginner in lua
I'm not going to nitpick, but most of what you're saying here just plain isn't true.
__________________
"There's only one thing that I know how to do well and I've often been told that you only can do what you know how to do well, and that's be you-- be what you're like-- be like yourself. And so I'm having a wonderful time, but I'd rather be whistling in the dark..."
  Reply With Quote
01-31-10, 07:50 AM   #8
Cladhaire
Salad!
 
Cladhaire's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Jul 2005
Posts: 1,935
Your claims about local variables taking any memory is just patently false and uninformed. See the following:

Code:
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> function foo() local a = {}; b = a; end
> function foo2() b = {}; end
> collectgarbage("collect"); collectgarbage("collect")
> = gcinfo()
27
> collectgarbage("collect"); collectgarbage("collect")
> collectgarbage("stop")
> for i=1,1e6 do foo() end
> = gcinfo()
62529
> collectgarbage("collect"); collectgarbage("collect")
> collectgarbage("stop")
> for i=1,1e6 do foo2() end
> = gcinfo()
62529
__________________
"There's only one thing that I know how to do well and I've often been told that you only can do what you know how to do well, and that's be you-- be what you're like-- be like yourself. And so I'm having a wonderful time, but I'd rather be whistling in the dark..."
  Reply With Quote
01-31-10, 08:33 AM   #9
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Something is in the memory as long as it can be accessed. That's the rule I follow and it seems to always apply.

Code:
local a = function() end
Now "a" doesn't actually contain "function() end", there is a memory slot assigned to "function() end" which "a" links to.

Code:
b = a
a = nil
This actually does use memory because "b" is still linking to the memory slot that contains "function() end".

Code:
b = nil
And now memory usage is 0 again because nothing links to the slot containing "function() end" anymore, so the Lua garbage collector destroys that slot.
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
01-31-10, 08:36 AM   #10
Cladhaire
Salad!
 
Cladhaire's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Jul 2005
Posts: 1,935
Originally Posted by nightcracker View Post
Something is in the memory as long as it can be accessed. That's the rule I follow and it seems to always apply.

Code:
local a = function() end
Now "a" doesn't actually contain "function() end", there is a memory slot assigned to "function() end" which "a" links to.

Code:
b = a
a = nil
This actually does use memory because "b" is still linking to the memory slot that contains "function() end".

Code:
b = nil
And now memory usage is 0 again because nothing links to the slot containing "function() end" anymore, so the Lua garbage collector destroys that slot.
Yes, but that has absolutely nothing to do with local variables, or the scope of local variables. Of course if you retain a reference to a collectable object then it cannot be collected. But that's not what you said, nor the advice you gave, hence why I responded.

The fact of the matter is unless you are creating tables or coroutines in an OnUpdate thread, you are not going to significantly affect the performance of World of Warcraft. An arbitrary memory usage number does not correlate to performance.
__________________
"There's only one thing that I know how to do well and I've often been told that you only can do what you know how to do well, and that's be you-- be what you're like-- be like yourself. And so I'm having a wonderful time, but I'd rather be whistling in the dark..."
  Reply With Quote
01-31-10, 09:27 AM   #11
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
Originally Posted by Cladhaire View Post
Your claims about local variables taking any memory is just patently false and uninformed.
You're the better programmer so I believe you ... still
http://my.morphosi.net/ButtonFacade_test.zip uses with mainly the changes
mentioned above minimal memory(down from 30-40mb in a raid to 2-3mb).
Thats why I came to believe what I wrote ...
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
01-31-10, 09:31 AM   #12
Cladhaire
Salad!
 
Cladhaire's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Jul 2005
Posts: 1,935
I don't dispute the differences that you see, just what you're attributing to. It's very likely they are leaving resources bound somewhere that aren't able to be garbage collected and that is causing the issue. I'm just trying to say that the conclusion you're drawing based on this is not correct. Local variables are not wrong, and they consume no memory.
__________________
"There's only one thing that I know how to do well and I've often been told that you only can do what you know how to do well, and that's be you-- be what you're like-- be like yourself. And so I'm having a wonderful time, but I'd rather be whistling in the dark..."
  Reply With Quote
01-31-10, 09:50 AM   #13
Amenity
Guest
Posts: n/a
Originally Posted by Cladhaire View Post
The fact of the matter is unless you are creating tables or coroutines in an OnUpdate thread, you are not going to significantly affect the performance of World of Warcraft. An arbitrary memory usage number does not correlate to performance.
Originally Posted by Amenity View Post
And just to point out (since everyone seems memory-crazed these days), 40MB is nothing for today's computers. You can't even fit a Britney Spears CD in 40MB without dumping data. As I'm sitting here typing this, Firefox is using four times as much memory uploading pictures of my kids blahblahblah more ranting from that Amenity person...
Got that covered. I'm still wondering why people are obsessed with memory use, yet completely ignore CPU time when this is a very CPU-intensive game in terms of real performance.
  Reply With Quote
01-31-10, 10:09 AM   #14
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
Originally Posted by Amenity View Post
Got that covered. I'm still wondering why people are obsessed with memory use, yet completely ignore CPU time when this is a very CPU-intensive game in terms of real performance.
Keeping memory usage low does not mean ignoring cpu usage.
You can optimize for both. But you're right cpu usage is more important.
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
02-01-10, 11:37 PM   #15
alimjocox
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Oct 2009
Posts: 96
Post

so when programming .lua files how to maintain cpu usage then? lol same reasons? functions and tables?
  Reply With Quote
02-02-10, 04:44 AM   #16
Cladhaire
Salad!
 
Cladhaire's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Jul 2005
Posts: 1,935
At the level you're talking, neither of these really matters.
__________________
"There's only one thing that I know how to do well and I've often been told that you only can do what you know how to do well, and that's be you-- be what you're like-- be like yourself. And so I'm having a wonderful time, but I'd rather be whistling in the dark..."
  Reply With Quote
02-02-10, 06:40 AM   #17
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
Originally Posted by alimjocox View Post
so when programming .lua files how to maintain cpu usage then? lol same reasons? functions and tables?
Many jobs/functions in wow are repeated on certain conditions. The more often
you have to repeat a job/function the more you should check if you can reduce
calling the API. For example a loop through your spells can be done everytime
you check your cooldowns or you can make a list of your spells once and then
run trough the list and only rebuild the list when you learn a new spell.

Things that dont change often are worth to be kept stored instead of
making a query everytime you need it (UnitName('player') eg).
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » mem usage

Thread Tools
Display Modes

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