User Tag List

Page 1 of 4 1 2 3 ... LastLast
Results 1 to 10 of 34

Thread: Help with garbage collection?

  1. #1
    Clicker Multimedia Fusion 2SWF Export Module

    Join Date
    Sep 2006
    Posts
    1,537
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Help with garbage collection?

    Heres my problem.

    I've got a game that creates an array in lua via a table, of size 500x500x10 or so, filling up data over the course of 10 seconds; one of the indexes is the frame #. So after 500 frames, it returns to the beginning, and starts overwriting old data; every time it loads an index, it erases the previous one

    (so my code looks something like this
    array[x] = [];
    array[x][y][z] = ....;


    My problem comes with lua's garbage collection scheme. Clearly, this array takes up a HUGE amount of RAM during the runtime. The game's memory usage will constantly increase; it starts at 18 megabytes at the start of the frame, and increases by about 1 megabyte per second up until it hits nearly 70 megabytes of memory. Then *BAM*, the garbage collection cycle runs, and it drops down to ~30 or so megabytes (The size of the data actually in use by the array).

    However, when this cycle runs, the game takes a huge framerate drop. Killing those 30+ megabytes of allocated memory makes my game stutter every 40 seconds or so, dropping it from 50 FPS to 35 FPS, since that cycle took so long to process.

    So letting the garbage run out of hand seems to overload it so terribly that I can't use it at the runtime without framerate drops. Now, my initial reaction was that I would simply have to run a garbage collection cycle frequently. However, something seems terribly wrong; by just modifying my code to run:

    collectgarbage("collect");

    every frame of gameplay, what happened was that the game took a huge constant hit of framerate; drastic, something like 50 --> 40 FPS.

    Running the cycle once every 5 seconds or so caused the tiniest stutter ever 5 seconds. The only thing is; that doesn't make much sense. The game is only writing/freeing less than a megabyte per frame, something my computer should have no trouble handling. The game indeed caps out at ~32 megabytes of memory instead of constantly crawling upwards, which is good, but it appears that every time I run lua's garbage collection, even though the smallest changes to my table/array have been made, it freaks out.



    Now, my suspicion would be this: That the way Lua has tables implemented, each time it frees up the memory from the table, it is doing something funky that involves the entire size of the table, like recreating it, or so on, due to an inefficient implementation. If this is true, or even if it isn't, does anyone know what kind of tactics I could use to make my project more efficient? Is there some issue with the means with which I am instantiating/destructing my table entries that would cause them to collect poorly, something that wouldn't surprise me? In the worst case scenario, I'm looking into the merits of using some alternative data storage technique like heck even LUASQL to interface with.

    If it helps, my code looks like this (a section of it):
    [spoiler]
    Code:
    --this is invoked once per frame before it updates
    function clearTimeStep(timeStep)
     timeArray[timeStep] = {};
    end
    
    function update(timeStep)
     for k=1, maxObjects do
      updateObject(timeStep,k);
     end
    end
    
    function updateObject(timeStep,id)
     for i=timeStep,timeStep do
      for j=id,id do
       timeArray[i][j] = {};
       timeArray[i][j]["X"] = mmf.Object.GetX(id);
       timeArray[i][j]["Y"] =  mmf.Object.GetY(id);
       timeArray[i][j]["ValA"] = mmf.Object.GetValue(id,1);
       timeArray[i][j]["ValB"] = mmf.Object.GetValue(id,2);
       timeArray[i][j]["ValC"] = mmf.Object.GetValue(id,3);
       end
      end
     end
    end
    [/spoiler]

  2. #2
    Clicker Multimedia Fusion 2
    Retriever2's Avatar
    Join Date
    Jun 2006
    Location
    United States
    Posts
    502
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    Garbage collection is an expensive process, even if there isn't a lot of garbage to clean up there is still a high overhead to calling the collector. That's why it tries to wait so it can amortize the cost. You could keep trying to find a suitable interval for calling the GC.

    If worst comes to worst, you may want to look into writing a C Module where you can statically allocate a huge chunk of space for your data, which you would just keep overwriting rather than having to constantly recreate the data tables (as is the case with Lua - it's not because it's inefficient, it's just not tuned for that kind of use).

    Actually, before you dive into any of that, you might be able to partially mitigate your problem by removing the line "timeArray[i][j] = {};", and either creating your table skeleton ahead of time or putting a check around it. You might reduce the amount of garbage you're producing because you'll at least retain the table rather than discarding it. Whether or not it can reuse the values, I'm really not sure. It depends if number values are treated as a primitive or not.

  3. #3
    Clicker Multimedia Fusion 2SWF Export Module

    Join Date
    Sep 2006
    Posts
    1,537
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    Hrmm I was looking at it and indeed, while the overhead on the GC is low in itself, the fact that its mark/sweep algorithm seems to count every single object sure seems to take a huge chunk of time like you said.

    But yeah you might be right that I could just create a skeleton table and overwrite individual values instead of discarding the entire timestep entries, since they'll be overwritten with data of the same format. The problem with that is twofold; the data will start filling in the table somewhat randomly, leaving behind remnant data on later frames that doesn't actually exist in the array, so the logic might get difficult (If I had object ID 21 leased to an object on frame #31, it would write in that data, but if it doesn't exist on frame #531, the data would still be left idling in that entry, even though no such object existed). Another problem with this is that as the table gets more and more filled in, the amount of memory used by the array would only go up and up and up and approach the worst case scenario, since it would never be cleared out. And since 90% of the time I'll only be using 10% of the table, that could have a negative impact on gameplay in itself, but I'll try testing it. I don't like the thought of using up the full 500x500x8 size array worth of memory, but if it proves to be something a normal computer can field, I'll just use the skeleton approach


    But yeah that might really help it if I can get the logic working, thanks. I suppose that writing a C Module that manually allocates the memory itself would create a workable solution if that doesn't work, so its definitely something I'll look into.

  4. #4
    Clicker Multimedia Fusion 2SWF Export Module

    Join Date
    Sep 2006
    Posts
    1,537
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    Hummm well! That appears to work!
    My only problem is that I have to generate the 58 megabytes of array each time the player loads the game now Fortunately, I can have it instantiate the 3rd index of the array as it generates it; running a 500x500 loop when the lua loads instead of the 500x500x8 loop. But still... 58 megabytes of RAM constantly needed, minimum! Lordy lordy this is going to be one hog of an app. At least its stable now, thanks!

    Humm I'll have to add something in there to control when the maximum cases are in, since without losing any size, worst case scenarios can make it look like this:



    I figure just some common sense code to free the unused memory whenever the game detects that the number of objects exceeds a number, then returns below it, ie whenever the number of particles on screen spikes. It would cause a little slowdown, but it could easily free 100+ megabytes of memory, which is a little ~_~

  5. #5
    Clicker Multimedia Fusion 2
    Retriever2's Avatar
    Join Date
    Jun 2006
    Location
    United States
    Posts
    502
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    A C Module approach would cost you about 16Mb (same approach, the complete amount of data is allocated up front).

    You could try selectively killing off dead objects, NILing out attributes, and maybe strike some sort of balance between size and GC time. CPU and memory are pretty much a universal trade-off in computing.

  6. #6
    Clicker Multimedia Fusion 2SWF Export Module

    Join Date
    Sep 2006
    Posts
    1,537
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    Yeah, what I'm looking at right now is running a selective garbage collection scheme inside of lua. Normally CPU and memory are so abundant that MMF never needs to worry about them but I guess I'll have to worry about that trade-off, ehehe.

    I figure I'll create a switch that gives it the ability to run the delete/create version of the table for a little while, and then call a garbage collector via lua at the end of the cycle, in order to wipe it, whenever it exceeds whatever threshold. In effect it would be almost exactly what lua is doing in the first place, except instead of just being able to set a threshold like it would give the choice, it would also let me adjust how much it is deleting at a time to stagger it a little.

  7. #7
    No Products Registered

    Join Date
    Aug 2006
    Posts
    984
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    you could try changing how often the gc runs but apparently that's a touchy process and probably wouldn't improve your situation

    lua does do some weird table things, like it won't shrink one if you nil most of it out, at least until you write a few values back into it; however i believe those only affect the hash part which you probably aren't using (unless for whatever reason it's wanting to throw your integer indices into the hash part

    of course you could always disable the gc entirely (and re-run it when you can afford to), but obviously that's probably a really bad idea for what you're doing

  8. #8
    Clicker Multimedia Fusion 2SWF Export Module

    Join Date
    Sep 2006
    Posts
    1,537
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    Well I'm trying to run a bit of a balance between the two by defining the X/Y axes of the 3-dimensional array off the bat, and having it only destruct/collect array elements whenever the number of objects in the game spikes (by comparing the ratio of maximum to minimum objects, and activating it when it goes above 1.5 and then back below 1.25). My hope is that this would create a safety catch that would free up the memory whenever a worst case scenario comes along (the player shoots a million projectiles somehow), and recover from it by freeing up the memory. It would mean the game might spike above 200+ megabytes of RAM, which is pretty nasty.

    Unfortanately the huge array size is a pretty crux part of the game. At best I can shrink it by maybe 60% by lowering the maximum object cap from 1000 to 500, and stacking a few variables on top of each other.

    I think disabling the GC isn't so terrible here. As long as I'm only overwriting the array, I'm never actually giving lua any bytes to throw away in the first place, so it would never have to run. I figure the garbage collection should only run (and the game should only free up the array) whenever the active portion of the array spikes up and then down. Putting in a naive activation threshold might cause the collector to run nonstop on larger levels, and thus both use up more memory *and* slow down the game, whereas recovering from large memory usages could cause a momentary lag spike, but free up the majority of the memory.

    My concern is this; would it really be worth freeing up the memory at all? If the game is going to use up 183 megabytes of RAM in the worst case, should I just allocate all that off the bat and never free it up at all, or will there be any tangible benefits to releasing it. Will there be some computers that will run slowly when the RAM becomes filled, and thus benefit from releasing the chunk? I mean it seems ridiculous and unstable for me to have an MMF app using up 200ish megabytes of RAM, but do I actually benefit more from releasing it than just hogging it all up? My program would be barely using an ounce more from anything else, so I'm not entirely sure.

    I mean, what sort of brick walls DO I run into by using up that much RAM?

  9. #9
    Clicker Multimedia Fusion 2
    Retriever2's Avatar
    Join Date
    Jun 2006
    Location
    United States
    Posts
    502
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    If you're always storing the same attributes, you should try using sequential integer indices instead of string keys. I did a little test with your code, and got huge memory savings (85MB down to 54MB. Given a 9MB overhead, that's 76 down to 45, or a ~40% reduction. When I used more attributes per table, my savings ratio was closer to 50%).

    The reason lies in how Lua stores its tables. Contiguous integer indices are stored in a basic array, and string indices (and outlier indices) are stored in a hash table. The hash table itself, in order to have fast insert and lookup properties, has to reserve extra space and thus has a higher overhead. Each repeated string index also has a stiff memory overhead, compared to an integer index which in this case should be implicit (doesn't have to be stored at all).

  10. #10
    No Products Registered

    Join Date
    Mar 2007
    Location
    Sydney, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Re: Help with garbage collection?

    I dont understand what problem you are having.
    My map editor uses a lua array that can use up to 500x500x12 slots. My map size is variable though so the x and y will be dependent on the map size. I have no problem with writing and reading values to this array at all. Im not sure what you mean by garbage collection though. Is that a command you call from lua itself? Im just overwriting values in each slots, is that different to what your doing?

Page 1 of 4 1 2 3 ... LastLast

Similar Threads

  1. OpenGL collection
    By Min in forum Extension Development
    Replies: 226
    Last Post: 2nd January 2014, 12:36 AM
  2. Garbage Collection
    By fawfulfan in forum Multimedia Fusion 2 - Technical Support
    Replies: 14
    Last Post: 19th August 2012, 10:50 AM
  3. Garbage Collection For IOS
    By sinister in forum iOS Export Module Version 2.0
    Replies: 1
    Last Post: 25th August 2011, 11:49 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •