Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Require(module) and package.loaded["module"] = nil : is it recommended not to use it frequently? — Gideros Forum

Require(module) and package.loaded["module"] = nil : is it recommended not to use it frequently?

MellsMells Guru
edited August 2012 in General questions
Hi,

I use require() to load some datas but I need to free it once the player reaches the end of the level, to require it again (but different file).
I know that I could use other ways to load datas (and I already do), but in a special case it's very handy to be able to use require().

So :
is it not recommended to require() and package.loded()= nil frequently and should I avoid it?

Dislikes: DoradoLab

twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
+1 -1 (+0 / -1 )Share on Facebook

Comments

  • Hi @Mells

    I often use package.loaded[moduleName] = nil to remove unneeded module from memory. And from my experience, it works well. You could read the drawback more about using require for module here http://lua-users.org/wiki/LuaModuleFunctionCritiqued
    have fun with our games~
    http://www.nightspade.com
  • MellsMells Guru
    edited September 2012
    Hi @Nascode thank you for this answer.
    I did many tests in my own apps also and it seems that it works well but I'm wondering if this is scalable.

    I have read the link that you suggested but honestly it was a bit above my skills :)
    I didn't understand clearly what were the benefits and the trade-offs.

    Well, I'll try and see if I don't get too many negative feedbacks :p
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • atilimatilim Maintainer
    edited September 2012
    @Mells, on the other hand, I prefer using loadfile instead of require. Basically these two work very similarly but loadfile doesn't have any side effects(?).
  • It's generally considered in programming that "side effects" from functions are "bad" and should be avoided as much as possible.

    I'd stick to the loadfile approach - cann't you just "loadfile" into a table, execute your code and then just nil out the table and call the garbage collector a few times ?
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • @atilim @techdojo
    Here is a simple example : I need to load my background (will use loadfile from now)
    bg = loadfile("1/background.lua")

    So I was freeing memory with :
    bg = nil
    package.loaded["1/background"] = nil


    Because later, I want to purge it to replace background with :
    bg = loadfile("2/background.lua")

    So @techdojo can you confirm that are you suggesting that I just do :
    bg = loadfile("1/background.lua")
    (...)
    bg = nil
    collectgarbage()
    collectgarbage()
     
    bg = loadfile("2/background.lua")
    ?

    If that the case, will niling free bg *and* 1/background.lua?

    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • To the best of my knowledge - loadfile will just allocate a table, fill it with the contents of 1/background.lua and assign bg to hold it's reference.

    Setting bg to nil will then cause the reference to that table to be "lost" and therefore suitable for garbage collection at some future point (providing of course there are no other references to it or it's contents).

    Calling the garbage collector two or three times will then help to "speed up" the process of collection so the memory *should* then become available (it's interesting to print the value of collectgarbage("count") after each call and see what a difference the extra calls make)

    Then setting bg to another loadfile should start the whole process of again.

    FWIW - If background.lua doesn't contain any "code" just a table then you might be better to serialise it to a JSON file and then just load in the string and re-encode it later.

    To be honest - I've never tried your approach and so it might be interesting to try it later and see what happens - as an aside, I wonder what will happen if you serialise a table that contains code into a JSON file and try and save / load that ????
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • MellsMells Guru
    edited September 2012
    @techdojo
    I'll try.
    FWIW - If background.lua doesn't contain any "code" just a table then you might be better to serialise it to a JSON file and then just load in the string and re-encode it later.
    basically background.lua constructs the bg (create a bg container and its childs : several layers, foreground, blending effects for each, animation for clouds, etc).
    background.lua returns a bg container.

    I made the choice to load the file because it fits the architecture of my project well.

    Memory leaks

    Note : how do you check, constantly, if you don't have a memory leak?
    I have added this line to my project :
    bird1:addEventListener(Event.ENTER_FRAME, function() print(collectgarbage("count")) end, self)
    I saw the number raise, panicked, excluded several files from the project but nothing changed.

    Then I added the same line to a very basic example that is available with Gideros Studio and the same happened.
    So how do you make the difference between the real collectgarbage count, and the number that is rising because you are printing this count on each frame?

    EDIT
    OK my last question was idiot.
    Should have added :
    collectgarbage()
    collectgarbage()
    collectgarbage()
    collectgarbage()
    collectgarbage("count")
    Adding / removing children and memory usage

    Collectgarbage()

    But still, how do you know how much memory is taken by print (collectgarbage("count")) itself?
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • You'll be better off with

    print(math.floor(collectgarbage("count"))) otherwise it'll generate a string to hold the value which in itself generates more garbage :)

    Think of the "count" as a "guide", what I do is usually collect all the garbage when I enter / exit a screen. I then display this (during development) and then enter / exit the screen a few times, what your looking for is the number to kinda stay constant between the screens. You will often allocate some stuff as you enter the screen for the first time and keep hold of it so you have to be aware of that.

    Also there maybe a little fluctuation as well - this is normal, what your looking for generally is a pattern of numbers that repeat over x number of iterations, if you see this then you can be sure your not leaking.

    Normally if you do have a leak then you'll be able to notice it fairly quickly if you use this method.

    Case in point - I've been debugging a scroll view and I noticed that the GC count was going up even though I KNEW I wasn't allocating anything, when I added a single collectgarbage("collect") call each frame the count stayed constant. What I ascertained is that behind the scenes the touch event system was generating a bit of garbage which "eventually" would have been picked up by the lua runtime - however because I was forcing it every frame it had the effect of keeping it under control otherwise when the GC finally did run you might have got a periodic drop in framerate if it had too much work to do.
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • MellsMells Guru
    edited September 2012
    @techdojo
    Very informative. Thank you very much :)
    This morning I was a bit panicking to see the number rising so much, then I tried print(math.floor(collectgarbage("count"))) and it seems stable.

    Getting closer to my goal, I'm like :
    image

    Likes: techdojo, deniz

    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
    +1 -1 (+2 / -0 )Share on Facebook
Sign In or Register to comment.