Why defining class as final improves JVM performance?

13,324

Solution 1

Virtual (overridden) methods generally are implemented via some sort of table (vtable) that is ultimately a function pointer. Each method call has the overhead of having to go through that pointer. When classes are marked final then all of the methods cannot be overridden and the use of a table is not needed anymore - this it is faster.

Some VMs (like HotSpot) may do things more intelligently and know when methods are/are not overridden and generate faster code as appropriate.

Here is some more specific info on HotSpot. And some general info too.

Solution 2

An old, apparently no longer but still largely relevant, article on this from IBM developerWorks, which states:

The common perception is that declaring classes or methods final makes it easier for the compiler to inline method calls, but this perception is incorrect (or at the very least, greatly overstated).

final classes and methods can be a significant inconvenience when programming -- they limit your options for reusing existing code and extending the functionality of existing classes. While sometimes a class is made final for a good reason, such as to enforce immutability, the benefits of using final should outweigh the inconvenience. Performance enhancement is almost always a bad reason to compromise good object-oriented design principles, and when the performance enhancement is small or nonexistent, this is a bad trade-off indeed.

Also see this related answer on another question. There's also the equivalent question for .Net, discussed here. SO discussion, "Are final methods inlined?" On a question titled "What optimizations are going to be useless tomorrow," this one appears on the list.

Note also that there is an entangling of the effects of final classes vs. final methods. You may get some performance benefit (again, I don't have a good reference) for final methods for sure, as it could cue the JIT to do inlining it couldn't otherwise do (or not so simply). You get the same effect when you mark the class final, which means that all the methods are suddenly final as well. Note that the Sun/Oracle folks claim that HotSpot can usually do this with or without the final keyword. Are there any additional effects from having the class itself final?

For reference, links to the JLS on final methods and final classes.

Solution 3

Not knowing the implementation of every particular JVM, I would theoretically say that if a JVM knows that a pointer to an object is a pointer to a type that is final, it can do non-virtual function calls (i.e., direct vs. indirect) to a member functions (i.e., no indirection through a function pointer), which may result in faster execution. This may also in turn lead to inlinining possibilities.

Solution 4

Marking classes as final allows further optimizations to be applied during the JIT stage.

If you are calling a virtual method on a non-final class, you don't know whether the proper implementation is the one defined in that class, or some sub-class that you don't know about.

However, if you have a reference to a final class, you know the specific implementation that is required.

Consider:

A extends B
B extends C

B myInstance = null;
if(someCondition)
   myInstance = new B();
else
   myInstance = new C();
myInstance.toString();

In this case, the JIT can't know whether C's implementation of toString() or B's implementation of toString() will be called. However, if B is marked as final, it is impossible for any implementation other than B's to be the proper implementation

Share:
13,324

Related videos on Youtube

Maxim Veksler
Author by

Maxim Veksler

Doing healthy things at K Health

Updated on December 06, 2020

Comments

  • Maxim Veksler
    Maxim Veksler over 3 years

    Quoting from http://sites.google.com/site/gson/gson-design-document:

    Why are most classes in Gson marked as final?

    While Gson provides a fairly extensible architecture by providing pluggable serializers and deserializers, Gson classes were not specifically designed to be extensible. Providing non-final classes would have allowed a user to legitimately extend Gson classes, and then expect that behavior to work in all subsequent revisions. We chose to limit such use-cases by marking classes as final, and waiting until a good use-case emerges to allow extensibility. Marking a class final also has a minor benefit of providing additional optimization opportunities to Java compiler and virtual machine.

    Why is this the case? [If I would guess: of JVM knows class is final it does not maintain method override tables? Are there any other reasons?]

    What is the benefit in performance?

    Does this applies to classes that are frequency instantiated (POJO?) or perhaps to class that are holders static methods (Utility classes) ?

    Are methods defined as final also can theoretically improve performance?

    Are there any implications?

    Thank you, Maxim.

    • Anon
      Anon over 13 years
      I'm sure that if you searched SO, you'll find an answer to this; I remember one just a few days ago. But regardless, I recommend that you ignore that last sentence; the rest of the paragraph is what's important.
    • Maxim Veksler
      Maxim Veksler over 13 years
      I'm asking for learning only purposes. Would love a link because I haven't found such (Did ran a quick search before asking).
    • andersoj
      andersoj over 13 years
      Agreed, the benefit of marking classes final has more to do with documenting their design (or lack thereof) for extensibility than performance. (On the other hand, that's not what @Maxim Veksler asked...)
    • bestsss
      bestsss over 12 years
      I know no relatively sane JVM that skips CHA (class hierarchy analysis), so final classes improve nothing.
    • arkon
      arkon almost 11 years
      From what I understand, it's the JIT that does any optimization on final not the JVM. See this article for more details.
  • andersoj
    andersoj over 13 years
    Is there documentation that HotSpot or any of the other major JVM vendors exploit this? Has anyone measured the effect recently in production code?
  • Steve Kuo
    Steve Kuo over 13 years
    The Sun JVM is smart enough that if no subclasses have been loaded, it treats the base class's methods as non-virtual.
  • Steve Kuo
    Steve Kuo over 13 years
    The JVM does know if there's a subclass because it keeps track of which classes have been loaded. If B and C are never loaded then it knows all of A's methods can be called directly.
  • matbrgz
    matbrgz over 13 years
    It was true in the VERY old days. When we banged rocks together to get ones and zeros and nulls.
  • andersoj
    andersoj over 13 years
    @Thorbjørn: Banging rocks together sounds lots more productive than most of the software development I see... ;-) Presumably HotSpot does all the right things -- can we assume that all the Java compilers and JVMs have finally caught up?
  • matbrgz
    matbrgz over 13 years
    @andersoj, high performant JVMs must do this to get enough speed (trading for memory). Small JVM's like JamVM cannot do as aggressive optimizations to stay smalle, so they cannot get quite as fast.
  • andersoj
    andersoj over 13 years
    @Thorbjørn: To clarify -- the time/space tradeoff you mention is the space to keep around inlined pieces of code (vs. efficiency in executing this code)?
  • matbrgz
    matbrgz over 13 years
    @andersoj. No, it is the space the JVM needs for its own internal datastructures describing the program being run. Basically the more calculations you can remember for later, the more advanced program transformations you can do.
  • andersoj
    andersoj over 13 years
    @Thorbjørn: Ah, good, that helps. I am not a JVM geek, but seem to have glancing blows with folks who are from time to time. Is there a canonical "VM nuances 101" to point folks to?
  • matbrgz
    matbrgz over 13 years
    @andersoj, I am not familiar with one. Also the various JVM code bases are vastly different so it is hard to generalize. IBM Developerworks has some nice articles.
  • andersoj
    andersoj over 13 years
    @Thorbjørn: Opened a new question on this topic: stackoverflow.com/questions/3963643/…
  • Christopher Barber
    Christopher Barber about 12 years
    Yes, but if it does that it also needs to recognize when a new subclass is loaded and force recompilation of any call to an
  • Christopher Barber
    Christopher Barber about 12 years
    (continued - BTW how retarded is it that I can't fix my comment?) ... base class method that was inferred to be final. The JVM is not likely to keep track of every such method so it will probably need to recompile all methods that invoke any of that base class's methods.