views:

64

answers:

3

From Effective Java 2nd Edition Item 7: Avoid Finalizers

"Oh, and one more thing: there is a severe performance penalty for using finalizers. On my machine, the time to create and destroy a simple object is about 5.6 ns. Adding a finalizer increases the time to 2,400 ns. In other words, it is about 430 times slower to create and destroy objects with finalizers."

How can one measure the time to create and destroy an object? Do you just do:

long start = System.nanoTime();
SimpleObject simpleObj = new SimpleObject();
simpleObj.finalize();
long end = System.nanoTime();
long time = end - start;
+2  A: 

That only measures the time to execute the finalize method. The vast majority of the cost of finalization will be in the special handling that the GC has to perform.

Stephen C
ok, what if I include Sytem.gc() just after simpleObj.finalize() above?
portoalet
And the cycles spent making the GC more complex. You **can not** microbenchmark this.
Tom Hawtin - tackline
@Tom Then how did Joshua Bloch measure the time stated in the book?
portoalet
@portoalet I don't have the book with me. However, Josh has worked on Java at Sun and Google. I'm guessing there are some large systems to benchmark there. (NIO has finalisers removed in 1.4.1, IIRC, because they caused performance problems.)
Tom Hawtin - tackline
hm ok, I guess I just have to ask Joshua how he did the measurement...The thing is I cannot find his email address?
portoalet
A: 

You could request the Runtime to perform Garbage collection via Runtime.gc(), but the Garbage Collector is not required to perform it right there and then:

  • The finalize() method is not to be called by you, but by the Garbage Collector
  • You could simply set the simpleObj to null, then call the Garbage collection to achieve a more realistic scenario
EdSG
+1  A: 

Instead of futilely trying to microbenchmark this, as Tom Hawtin said above, the best approach is to examine the time to do a few hundred thousand cycles of creation and destruction, and divide by number of cycles.

This approach is the best in a lot of situations where the code you write is not the only code involved - where you're dependent on system calls, or external resources.

I think that's what Joshua Bloch did in this case, but my copy is upstairs and I'm feeling lazy.

CPerkins
well the book does not say how Josh does the microbenchmark. So basically you are saying put the code I have above in a for loop, and then average out the time?
portoalet
Yup. Do your best to exclude any other setup costs, classloading, etc (so for example, create and null a few instances before beginning the timing).
CPerkins