Does anyone have any information on what optimisations (I realise this is implementation specific) most JVMs will do when confronted with a final object? In particular, an array of final objects in Java? For example:
final class A { }
A myArray[] = new A[10];
If the class “A” is final then it can have no subclasses, so it seems like it would be possible to allocate (not calling constructors) the entire array (i.e. malloc(sizeof(A)*10)) and save on garbage collection/book keeping.
I severely doubt any JVM would bother to do that. In part because it would probably create extra book keeping. Any instance held both in the array and else where would have to dual modified to keep in line with the rules of the JVM.
eg.
The implementation you suggest would force a copy of
instanceto be created when the array is created, thus forcing the JVM to remember to change the contents ofvaluewhenever it was changed in the other instance of A.In response to your comment:
That’s an interesting idea and would work to a certain extent. However, your idea will wreck garbage collector performance. The reason for this is that the best JVMs don’t use reference counting. The best JVMs use a moving garbage collector. This technique traces from all root nodes (eg. Threads) to see what objects are referenced. All objects in the reference chain are moved into a contiguous block. Any memory outside of this block is considered free. No calls to dealloc or finalise or anything. This technique is VERY fast (in part due to the high “infant mortality” of objects in GCed languages). What’s more is that this technique doesn’t have to bother checking for circular references.
Back to the point: when the array drops out of scope the JVM will have to check if there are any other references to elements of the array and malloc new space for these objects before it can free up the memory of the array. This prevents the use of a “moving garbage collector” and we have to go back to inefficient GC techniques like reference counting. So whilst you idea seems good at first glance (and only for a certain edge case), it prevents other GC strategies that can be more widely applied and provide much greater efficiency savings.