Monday, June 28, 2010


New Release

I've just done a new RepRap release at Sourceforge. This will probably be superseded quite quickly (we are in the process of standardising the M Codes used to drive the machine, which won't take long).

The host software now runs an awful lot faster when it is slicing RFO files and STL files. This is because I removed something that, in my ignorance, I had thought would make it run faster, but which experimentation has now shown had the opposite effect: I had put a finalize() function in all the geometry classes. That seemed reasonable - give the garbage collector a bit of a hand to tidy things up. But what it actually does is to subvert the garbage collector and to put unreferenced memory into a queue for later removal; a queue that rarely - if ever - seems to get acted upon. If someone can explain why this is a good idea, I'd love to hear it.

Meanwhile, all the finalize() functions are gone, and the host software now runs pretty zippily... (It uses a lot less memory, too.)

The algorithm it uses to find outlines of slices has also been changed to Marching Squares, which seems both more reliable and faster.

The new software now also supports heated beds.


Great news to see a new Release. I have already tested it and can see a massive performance speedup. I found some usability issues with the previous release, which I detailed here:

Is there a bugzilla I could submit these issues to? it would be great to see these minor niggles fixed up in an upcoming release.
fyi - this seems to work in OSX 10.6.4 if you use this version of librxtxSerial I haven't fully tested it yet, since I don't have a functioning extruder.
Here is my understanding of the way that finalizers are handled by the VM in Java:
When the Garbage Collector gets round to cleaning up unused objects, it detects those that have finalizers and adds them to a list - the finalizers are not run, nor are the classes collected at this point. The GC then cleans up all other classes as it sees fit.
Once the GC has done, the finalizer thread can continue through each of the classes in its list, running the finalizer method for each class, marking the class as finalized once it has done so (assuming it is not referenced by anything else, and can now be collected).
When the GC next has a sweep it will clear those classes that have been marked as having a finalizer, and have been finalized.

If you have a lot of classes with finalizers, as there is only one finalizer thread this can be a performance overhead, additionally it requires another GC cycle.

Unless you explicitly need a finalizer to do something very special, it is wise not to use it - after all it is not guaranteed to be run anyway if the JVM shuts down having never needed to do a garbage collection sweep.

Hope that makes some sense!
Giles - yes, we do need to get this working. When we've sorted out the move to Git we'll do that.

AndyT - It makes perfect sense, and it exactly concurs with the symptoms I observed. But what's the point? I can see why one might want to do something special when an instance of a class is finished with, and finalize() gives you a way to do that. What I don't understand is why this removes the item from the normal garbage collection process. Surely the rules should be something like:

Is this item out of scope and unreferenced?

If yes, run its finalize() function, remove the pointers from it to everything it points to, then flag its space on the heap as dead. If it doesn't have a finalize() function just do that other stuff.

Periodically run gc() over the heap.
Code in finalize() should never be able to block the GC e.g. with an infinite loop.
Thus the finalize() are run in their own thread.
The GC itself has become multithreaded a while ago but
there was little need to do this for the seldomly used finalize-thread.
Adrian, this might help with respect to the garbage collection discussion as it java has always handled it differently to the C++ and C world.

The issue being that you can not predicate when the gc occurs, and more specifically, the gc may never occur if you don't have memory issues.

finalize is not a destructor routine, it is used for special clean up cases (for example you have been using JNI).

(I.e. finalise gets called, you do the special clean up required and then the object is marked for clean up at some point).

I am guessing that the performance issues are down to the overhead of calling finalize on the ploygons (since there are quite a lot of them). The GC runs, and the process is.

GC all the functions without a finalize function or call the finalize function and deal with the object on the next GC when that happens.

The issue being you can not tell then the GC is going to happen.

I hope that makes sense as it is quite early in the morning for me.
The distribution contains configuration.h files for both the extruder and the gcode interpreter. They seem to be old and should be removed to avoid confusing reprap newbies like me.
finalize() - I see; and simplest to avoid it all together...

configuration.h - sorry; quite right. My own copies got bundled in; I should keep them separate...
Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to
Posts [Atom]