Proposal for finalizer optimization.
I am thinking about optimizing the implementation of finalizing. At present, finalizing imposes a high overhead to garbage collection. If an object has a finalizer, it must be collected twice, in case the finalizer creates a reference to the object somewhere. In the vast majority of cases this does not happen. The optimization would detect that the finalizer cannot create such references , and would mark the finalizer to run exactly before the memory of the object is released. What would be the best place to insert this optimization? Any other ideas?
Do you mean that you're planning to run the finalizer as part of the GC, just before it reclaims an object's memory? Tony Ramón García wrote:
I am thinking about optimizing the implementation of finalizing.
At present, finalizing imposes a high overhead to garbage collection. If an object has a finalizer, it must be collected twice, in case the finalizer creates a reference to the object somewhere. In the vast majority of cases this does not happen. The optimization would detect that the finalizer cannot create such references , and would mark the finalizer to run exactly before the memory of the object is released.
What would be the best place to insert this optimization? Any other ideas?
Yes, the idea is to run object.finalize() exactly before reclaiming object's memory. Ramon
Ramon, You really can't just call the finalizer from the GC. Usually, the GC works when the application threads are stopped (i.e., during a "stop-the-world" pause) and no Java code is running (and the finalizer is Java code). There might be some synchronization issues as well. Imagine that the finalizer wants to take a lock that another thread is holding; this would deadlock the GC, as the other thread is not running and is waiting for the GC to complete. Finally, finalizers are arbitrary Java methods that can take an arbitrarily long time to execute; if you run them as part of the GC, you'll introduce a lot of unpredictability on duration of the GC. Another bummer is that most finalizers call a native method to do some native resource reclamation. As a result, you can't do some static analysis over them (i.e., you'd have to analyze machine code, not Java bytecodes). Tony Ramón García wrote:
Yes, the idea is to run object.finalize() exactly before reclaiming object's memory.
Ramon
I am thinking about optimizing the implementation of finalizing.
To be honest I am not so sure wether this optimization makes a lot of sence, except for legacy code: Code that does not resurrect the object in the finalizer could also use WeakReferences+Queue - and otherwise when this (not recommended technique is used) there is no way to optimize anyway. lg Clemens
Thanks for the points. I think that they can be solved, for instance, by running the finalizer after the GC, but then deleting the object immediately instead of enqueing it again. Other option would be to call the finalizer, but don't wait for it, just leave it running and ensure that the memory is released afterwards. With regard to native method calls, finalizers can (and usually do, I think) call native static functions that do not receive the this argument, only the fields necessary for releasing native resources (such as the native file handle). On Nov 26, 2007 9:46 AM, Tony Printezis <tony.printezis@sun.com> wrote:
Ramon,
You really can't just call the finalizer from the GC. Usually, the GC works when the application threads are stopped (i.e., during a "stop-the-world" pause) and no Java code is running (and the finalizer is Java code). There might be some synchronization issues as well. Imagine that the finalizer wants to take a lock that another thread is holding; this would deadlock the GC, as the other thread is not running and is waiting for the GC to complete. Finally, finalizers are arbitrary Java methods that can take an arbitrarily long time to execute; if you run them as part of the GC, you'll introduce a lot of unpredictability on duration of the GC. Another bummer is that most finalizers call a native method to do some native resource reclamation. As a result, you can't do some static analysis over them (i.e., you'd have to analyze machine code, not Java bytecodes).
Tony
Ramón García wrote:
Yes, the idea is to run object.finalize() exactly before reclaiming object's memory.
Ramon
Ramon, Ramón García wrote:
Thanks for the points. I think that they can be solved, for instance, by running the finalizer after the GC, but then deleting the object immediately instead of enqueing it again. Yes, but this will not work on copying / compacting GCs, given that you can't just reclaim arbitrary space in such GCs (instead you free up space by moving live objects somewhere else). Other option would be to call the finalizer, but don't wait for it, just leave it running and ensure that the memory is released afterwards.
Ditto.
With regard to native method calls, finalizers can (and usually do, I think) call native static functions that do not receive the this argument, only the fields necessary for releasing native resources (such as the native file handle).
Some of them do, a lot of them probably don't. Tony
On Nov 26, 2007 9:46 AM, Tony Printezis <tony.printezis@sun.com> wrote:
Ramon,
You really can't just call the finalizer from the GC. Usually, the GC works when the application threads are stopped (i.e., during a "stop-the-world" pause) and no Java code is running (and the finalizer is Java code). There might be some synchronization issues as well. Imagine that the finalizer wants to take a lock that another thread is holding; this would deadlock the GC, as the other thread is not running and is waiting for the GC to complete. Finally, finalizers are arbitrary Java methods that can take an arbitrarily long time to execute; if you run them as part of the GC, you'll introduce a lot of unpredictability on duration of the GC. Another bummer is that most finalizers call a native method to do some native resource reclamation. As a result, you can't do some static analysis over them (i.e., you'd have to analyze machine code, not Java bytecodes).
Tony
Ramón García wrote:
Yes, the idea is to run object.finalize() exactly before reclaiming object's memory.
Ramon
-- ---------------------------------------------------------------------- | Tony Printezis, Staff Engineer | Sun Microsystems Inc. | | | MS BUR02-311 | | e-mail: tony.printezis@sun.com | 35 Network Drive | | office: +1 781 442 0998 (x20998) | Burlington, MA01803-0902, USA | ---------------------------------------------------------------------- e-mail client: Thunderbird (Solaris)
participants (3)
-
Clemens Eisserer
-
Ramón García
-
Tony Printezis