Thread Tools Display Modes
03-06-10, 04:45 AM   #1
Crowfeather
A Fallenroot Satyr
 
Crowfeather's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2008
Posts: 28
Memory usage and variables

As Iīm not really happy with the memory usage of my addon Iīd like to learn a bit about how lua allocates and releases memory for variables.

For example Iīve got a function that creates and fills a table adj. Every time the function is called some of the table values may have to be deleted, some new values may have come up and some existing values may have changed.
So far all I did was recreating the table with an local adj = {} statement and refill it with current values. Now from my testing it seems that doesnīt release the memory used by the original adj table but leaves it as garbage to be collected. Using if not adj then adj = {} end fixes the memory problem but that also means that anything that isnīt overwritten will remain in its old, obsolete state (eg. isnīt deleted).

I guess what Iīm asking is, whatīs the proper way to delete tables (or variables in general).
  Reply With Quote
03-06-10, 04:52 AM   #2
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
The only way to "delete" anything in Lua is to do what you were doing before - set it up to be garbage-collected. However, you can either explicitly set the variables to nil, or use table.wipe() before re-filling the table.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
03-06-10, 05:44 AM   #3
Crowfeather
A Fallenroot Satyr
 
Crowfeather's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2008
Posts: 28
Thanks for the fast reply.

Iīve tried both
Code:
if adj then table.wipe(adj) else adj = {} end
and
Code:
local adj = nil
adj = {}
The latter didnīt change anything, the former alleviated the problem somewhat (memory growth down from 0,95% to 0.81%). Unfortunatly I canīt make the table local if Iīm checking for its existance in an if clause because than it would be local in that if block only.

As a more general question assume Iīve got the following function
Code:
function foo()
  local a = 1
end
And this function is called frequently, does it always allocate new memory for the variable a? Iīm asking because Iīve got a lot of statements like
Code:
local allDmgAdj, constDmgAdj, refreshDmgAdj, instantDmgAdj = 1, 1, 1, 1
  Reply With Quote
03-06-10, 07:05 AM   #4
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
You won't get around garbage collecting, that's just how Lua works. And even you won't like it now, it's actually pretty great.
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
03-06-10, 07:43 AM   #5
Crowfeather
A Fallenroot Satyr
 
Crowfeather's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2008
Posts: 28
Originally Posted by nightcracker View Post
You won't get around garbage collecting, that's just how Lua works. And even you won't like it now, it's actually pretty great.
Thatīs not the point. Iīm not complaining about the way lua handles garbage collection or memory allocation - quite the opposite. I think itīs much more likely that somehow, somewhere Iīm still doing something horribly wrong and cause my addon to use much more memory than it ought to do.

Looking an profiling addon that watches memory usage and growth thereīre a few bigger addons that take up much more memory but for none of them the memory usage grows as fast as for mine. Thatīs even though thereīs not more data that needs to be stored but only the same variables that needs to be overwritten multiple times per second.
  Reply With Quote
03-06-10, 10:34 AM   #6
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by Crowfeather View Post
<snip>
Code:
function foo()
  local a = 1
end
And this function is called frequently, does it always allocate new memory for the variable a? Iīm asking because Iīve got a lot of statements like
Code:
local allDmgAdj, constDmgAdj, refreshDmgAdj, instantDmgAdj = 1, 1, 1, 1
No. The variable "a" would be allocated on the local stack (if applicable - strings, for example, are never released once allocated, so at that point "a" would simply be a reference to the segment of memory in which the string resides) and then promptly released when the function popped off of the stack.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
03-06-10, 12:17 PM   #7
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Though if you are calling it very frequently (in an OnUpdate, for example), then you may find it more beneficial to do this:

Code:
local a
function foo()
     a = 1
end
Here, the variable a is created outside of the function (thus its availability is not limited to the function's scope), but is only created once, as opposed to every time your function is called.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
03-06-10, 01:26 PM   #8
ravagernl
Proceritate Corporis
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 1,176
Originally Posted by Seerah View Post
Though if you are calling it very frequently (in an OnUpdate, for example), then you may find it more beneficial to do this:

Code:
local a
function foo()
     a = 1
end
Here, the variable a is created outside of the function (thus its availability is not limited to the function's scope), but is only created once, as opposed to every time your function is called.
I've seen some authors use this trick:
Code:
local FunctionFoo
do
    local a
    FunctionFoo = function()
        a = 1
    end
end
What is the advantage of this method comparing yours?
  Reply With Quote
03-06-10, 03:44 PM   #9
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
In Seerah's version, the "a" variable is visible to everything in the file below its declaration. In the do-block version, only the function defined directly below it knows about its existence.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
03-07-10, 08:47 AM   #10
Crowfeather
A Fallenroot Satyr
 
Crowfeather's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2008
Posts: 28
Thanks for all the answers, I think it already helped me lowering the memory usage of my addon significantly.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Memory usage and variables


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