lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On Sunday, July 28, 2013, Mark Hamburg wrote:
The memory issues in GC based systems are "interesting".

Thanks to non-incremental GC systems, what one most often hears concerns over are GC pauses. In Lua, even with its atomic phase, these do not generally seem to be a problem. Maybe they would matter for real time work, but if I were building something with even moderately hard real time constraints, I would probably avoid a number of things including not just GC but allocation as much as possible.

There is another cost to GC in the form of book keeping and cache pollution from the GC itself. On the other hand, reference counting also tends to come with a fairly high hit in book keeping overhead.

The big point and the one this piece focused on is what a GC system does to memory pressure. This is an area where Lua is unlikely to do any better than other GC’d systems except to the extent that it allows one to drive the GC faster thereby paying more in book keeping but reducing memory pressure.

This is basically about precision. A precise memory strategy would allocate memory no sooner than it is needed (that's generally the case for most strategies) and free it as soon as it was no longer needed. Imprecision leads to higher memory usage since it either involves allocating memory early or more often freeing it later.

A strict manual management strategy should be able to be absolutely precise right up until the program crashes because you get into a situation that the program can't handle. Or if it doesn't crash, there is a lot more copying of data structures — think about C++ vectors getting copied around just like they were integer values — which in its own way ups memory usage even if it remains precise.

Reference counting automates away most of this work and can be just as precise as the manual strategy provided you don't have cyclic structures and are good about clearing references. It does cost more in book keeping overhead both in space for the reference counts and time to maintain them.

Apple's autorelease pools reduce the book keeping overhead for reference counting at the expense of sacrificing some precision. Mostly this works well (modulo cyclic data structure caveats) but there is a classic failure mode in which one allocates a lot of temporary data without closing out an autorelease pool scope.

Apple's ARC doesn't really change the memory allocation behavior. It basically says that for the expense of having to do some notation work, the compiler can figure out where to insert the reference count adjustments. C++ programmers presumably say "Huh? Why not just use smart pointers?"

And then you get to garbage collection which doesn't fall prey to cycles and can generally collect just about anything that has become unreachable — weak tables in Lua 5.1 would be a potential exception — but it does so at the expense of being much less precise about when the space is collected.

Where this comes back to bite one is in cases where very large structures — e.g., huge tables or large bitmaps hanging off of a small userdata — become inaccessible. Basically, you have to wait for the system to cycle around and find that the memory is no longer reachable. Running the GC faster is one way to reduce this but it costs more time spent on GC. A secondary, manual system can do early frees for external resources, but knowing when it is safe to free gets one back into the same sort of problem that drives one to use GC in the first place.

Mark

On Jul 15, 2013, at 5:33 PM, Andrew Starks <andrew.starks@trms.com> wrote:

> On Mon, Jul 15, 2013 at 3:58 PM, Michal Kolodziejczyk <miko@wp.pl> wrote:
>> On 15.07.2013 20:24, Michal Kolodziejczyk wrote:
>>> Pozdrawiam,
>>>    Michał
>>
>> Sorry for that empty message, that was send by pressing accidentaly a
>> key on my android phone.
>> Back to the topic, I wondered if the planned garbage collector for
>> luajit 3.0 would help with memory management:
>>
>> http://wiki.luajit.org/New-Garbage-Collector
>>
>> OTOH, I wondered if a subset of lua with typed variables and no GC would
>> be possible (asm.lua, like asm.js from asmjs.org), and if that would
>> made any difference.
>>
>> Regards,
>> miko
>
> My take is that he's completely ignorant about Lua and that the
> article is much more about "mobile apps in web browsers" not native
> applications.
>
> So, in making his case, he lumps all languages together and puts Lua
> in the same box. One of his points is that, because _javascript_ does
> not allow you to control the GC, it precludes you from a critical
> opportunity to overcome one of GC's limitations, which is suspending
> it during critical points in the code.
>
> My guess is that, if he deemed it relevant, he could do a simple test
> and judge Lua against his points. I my experience and observation is
> that A) He makes great points, B) Lua backs his points up and C) Lua
> does the things that it needs to do in order to be a relatively
> performant garbage collected dynamic language.
>
> No fancy-new-GC required, as far as I can see.
>
> -Andrew
>

Thank you for this. It was a great read. That I saved as well. I'd suggest it as a blog post, if you have one. :)

It lead me to think that special cases, like the one that you mentioned, could be addressed with by making it so that `collectgarbage` would try to free an object, if the object was made as a weak value of collectgarbage, making it addressable as something to attempt to collect later:

myvar = i_make_big_obect()

collectgarbage.myvar = myvar

myvar = nil 

collectgarbage.myvar()

...would just try to free `myvar`, returning true if it was free and false if not.  This is most likely a use case that is not worthy of addressing. 

-Andrew