• Post Reply Bookmark Topic Watch Topic
  • New Topic

Temporary or single-use variables and HotSpot optimizations.  RSS feed

 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello:

Let's suppose that on the one hand I've this piece of code:



And on the other hand this one:



They both create a name combining an ID, a version and a subversion. But that's just for illustrating my question. I'm interested in what happens internally.

In the first piece of code, the variables id, version and subversion have the same scope. However, they don't need to be in use or live at the same time. Is the JIT compiler from HotSpot able to detect these situations and reuse space in the local variable stack?

In the second piece of code, the first impression is that the mentioned variables need to be in use at the same time. However, because each one is used in separate calls, they don't. This piece could be converted to the second. If the answer to the previous answer was affirmative, Is HotSpot "intelligent" enough to detect these cases too? Can it re-order the code in safe cases like this one?

Thank you.
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You would have to view the bytecode for those methods with javap -c in order to see whether there is any difference.
In both cases a String object for version exists. If those methods store any references to that object, it would be as a local variable which is deleted from the stack after the method completes.
I cannot tell how that object is handled in the getVersion() method.
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie: I'm sorry. Effectively I checked the output of javap before writing but forgot to mention it here :S . Basically both methods result in very similar code, but in different order, just as the Java code itself reflects:

Case A:




Case B:



Both methods use 4 words of the stack (I believe that's the right term). javac seems not to be able to reuse words if the variables are in the same scope, as advised in many articles. That's why I was wondering if the JIT compiler can do some "magic" here, he he he.
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I write FORTH code, too, so I have to get used to how a call stack works. If you need to use a value on the stack, it has to be pushed onto the stack first. If you use it twice, it has to be pushed onto the stack twice. The number of occurrences on the stack is equal to how often it is used.
Notice the StringBuilder reference appears twice: once it is used as the address of a StringBuilder object, and then it is duplicated (dup) so as to call the constructor. But the constructor is replaced by an <init> “method”.
Notice the Strings are recorded and stored and then used again later. What is recorded with astore is not the whole String, but a pointer (or more likely, a “handle”) to its memory location. I do not know where astore keeps its argument; try going through the JVM specification and seeing whether it gives any help. (I think the location would be different if any of those variables is marked volatile>.
Obviously the javac tool realises you have to get those values from the methods and pass them to append(), and it uses the same procedure for both. It is reassuring to see there is not significant difference between the two cases. As you said, same instructions in a different order.
You have not done any JIT (=Just ITime) compilation. That does not occur until the JVM runs. Yes, I believe HotSpot can reorder and optimise the code if required. Don't know much more than that , but there is probably something useful on the Oracle Java website about such optimisation. Start here.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Note that the Java compiler (javac) does not do much optimization; most optimization is done by the JVM and the JIT at runtime. By looking at the bytecode that javac produces, you won't see what the JVM and JIT do to optimize this.

However, we're talking about local variables in a method here. Whether you write code example #1 or #2 will practically not make any difference at all for performance or memory usage.

The HotSpot JIT contains a lot of sophisticated optimizations, but you really have to be an expert in the internals to know what exactly it does, and there are probably only very few people who are experts in this field. If you're really interested, you can have a look at the source code in the OpenJDK project. But it's not going to be easy to dive into that, because it's huge and complicated.
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie:
Jesper de Jong:

First of all, I want to thank you for your answers. I've noted down the links that you've provided me and will check them this weekend, with much patience. Although I agree that it's going to be difficult to find an answer. My skills in this field are very little and the documentation is massive, he he he.

In a few places I've read that JIT compilers for Java are allowed to reorder the code, as long as they don't violate the "happens-before" principle. This is mentioned in the second answer to this question: http://stackoverflow.com/questions/17247881/how-jit-schedule-the-execution-of-byte-code . However, after thinking about it carefully, I believe that the extra step of figuring out which positions of the stack are reusable might need an intense analysis and not be worth it.

Anyway, if I found some information, I would share it here. Thank you ;) .
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is also mention of code reordering in Brian Goetz's book. It is particularly important if you are multi‑threading.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, Brian Goetz' book explains everything about the "happens-before" principle, it's a highly recommended book if you want to know all the details about multi-threaded programming in Java.
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the recommendation. I've always wanted to get into concurrent programming. I started to read the official tutorials from Oracle, but couldn't practice it in depth... Maybe it's time for a new attempt ;) .
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!