Is the hotspot JVM Bytecode Interpreter a tracing JIT? - java

The question pretty much says it all, I've been looking around for an answer even through the VM spec but I it doesn't explicitly state it.

No.
There are some other JVMs with tracing JITs, though: HotPath and Maxine, for example.

Aside: for those who don't know what a tracing JIT is, the following description comes from this page:
Although tracing JITs are a complex technology, the core concept is about optimizing execution of the hot paths in a program. The emphasis is specifically on hot paths that return to the start of a path which sounds very much like a loop. However, the traditional definition of a programming loop is only a subset of these hot paths. The broader definition includes code that spans methods and possibly even modules. This broader definition of a loop is what’s called a trace.

Had to google what a "tracing JIT" was, but apparently it isn't.
> non-tracing JIT implementations (Sun’s Java VM
But it does optimise what you might call "hot spots".
How bytecode is optimised will not be part of the specification for the bytecode.

It's not even a JIT actually, let alone a 'tracing JIT', whatever that might be.

Related

A concrete Example of the effect of the JIT in java

So I am aware the java has just in time compilation (the JIT), which gives it an advantage over statically compiled languages like C++. Are there any examples illustrating the java JIT? Possible examples could be outperforming C or C++ code for a given algorithm? Or showing an algorithm's iterations getting faster with time (I am unsure if that would be an instance of the JIT). Or just any example which can show some sort of measurement of the existence of the JIT doing this? I ask this question because I have only ever read about the JIT and wish to prove it's existence as opposed to just believing in it like some sort of religious God.
Remark - If this question is too opinionated please comment and let me know why. I am just curious about the JIT and after using java for a few years still to this day am unaware of how I benefit from it, and if it lives up to the hype of outperforming its statically compiled counterparts.
Additional Information - I have read about when it does it, and am not looking for more information I will just need to believe is true, I want to see something which shows me doing what it is suppose to do.
EDIT - Good that I have allot of responses, what has been said is that comparing speed alone JIT optimised vs. C++ is not a good approach, and that a pure java comparison would be the least horrible. What about an example showing this with java:
So a JIT and Non-JIT optimised program doing the same are executed. At the start the JIT has not kicked in, and the program begins getting quicker whilst the static always has the same performance. Then the conditions change at 5.5 seconds or so and the application is being used slightly differently. The JIT has the ability to adapt to these changes again, firstly the time spikes and then it begins optimising again and can even reach a better optima becaue the application is being used slightly different.
Would this be an acceptable example to show a JIT? (I will endevour to achieve this and review everyones links and videos).
I do not think you can convincingly prove that java using JIT is faster than C/C++ statically compiled code.
You could find some code in java that beat its c/c++ implementation. For that you need to search for keywords like (benchmark,Java,JIT,C,C++ )
I have purposely not mentioned any code or links for the above because of my point below.
Most of the times people show java code beating statically compiled c/c++ in following ways
Find part where java is fast compared to c/c++(memory allocation)and write only code to highlight it.
Find weak points of c/C++ code and try to write java code that beat the c/c++ code in achieving the result.
Run code in environment where you have advantage like having fast hardware and good amount of memory .
My point being you are trying to find exception where java is faster that C/C++ and then generalizing it to the whole language. You could easily find more more examples of c/c++ beating java code just by using pointer in many algorithm.
Such code benchmark testing is of no value in real life application development.
Summarizing ( in real life application development )
Java was slow compared to c/c++ when it first came out. But in the past decade improvements made in JVM coupled with JIT,Hotspot etc have made java as good as C/C++. Java is not slow nowadays. But I would not call it fast over c/c++. Any difference in real life application development in negligible because of language improvement as well as better hardware.
You cannot generalize that java is faster than c/c++ by beating it one time in a particular environment with a particular algorithm or code.
You might find some interesting info in the following links
https://softwareengineering.stackexchange.com/questions/110634/why-would-it-ever-be-possible-for-java-to-be-faster-than-c
Is Java really slow?
Since question has been edited to now try and find the performance improvement of using JIT , I am editing my answer to add a few more points.
My understanding of JIT is that it improves the code that is most executed , to a version that can be run really fast by compiler. Most of the examples of JIT optimisation techniques I have come across shows actions which could also be done by the programmer but then would affect the readability of the program or may not confirm to the framework or coding styles the programmer is/has to use.
So what I am trying to say here is if you write a program that can be improved by JIT it will do so and you will see an increase in performace. But if you are someone who understand JVM and write java code that is already optimized then JIT may not give you much benefit.
So in effect if you see a performace improvement when running a program using JIT that improvement is not guaranteed for all java programs. It depends on the program.
These links below show some JIT improvements using code examples.
http://www.infoq.com/articles/Java-Application-Hostile-to-JIT-Compilation
https://plumbr.eu/blog/java/do-you-get-just-in-time-compilation
Anyway if we need to to differentiate the performance while using JIT, we would run a java program with JIT enabled and run the same program again with JIT disabled.
This link http://www.javacodegeeks.com/2013/07/java-just-in-time-compilation-more-than-just-a-buzzword.html has a case study on this topic and recommends the following
Assessing the JIT benefits for your application
In order to understand the impact of not using JIT for your Java application, I recommend that you preform the following experiment:
Generate load to your application with JIT enabled and capture some baseline data such as CPU %, response time, # requests etc
Disable JIT
Redo the same testing and compare the results.
This link http://people.cse.iitd.ac.in/~sbansal/csl862-virt/readings/CompileJava97.pdf does benchmark JIT and shows speed improvements over basic JVM interpretations.
To understand what JIT does to your code , you could use the tool JITwatch.
https://github.com/AdoptOpenJDK/jitwatch
The links below explain its utility.
http://www.oracle.com/technetwork/articles/java/architect-evans-pt1-2266278.html
http://zeroturnaround.com/rebellabs/why-it-rocks-to-finally-understand-java-jit-with-jitwatch/
First, you want to watch this video. It gives you tools to see the JIT in action.
Where I believe your questions is misled is that you are asking for an example of tailored code where you could potentially measure faster performance in some JVM-based language X vs some non JVM-based language Y (where, for instance, X is Java and Y is C).
This is not the way to think about the JIT. Unless you actually write a compiler for the JVM language by yourself, or have to debug some serious performance issue, and only after you have considered refactoring your code and seen it fail then you can delve that deep into details.
But otherwise, the principle is simple: the JIT is your friend and it does things right; all you have to do is write code which just works; if there are ways that the JIT can make it faster at runtime, it will most certainly do so.
There are countless examples on Stack Overflow of questions like "why is my code running faster all of a sudden?" - usually when people try to benchmark their code. The answer is, invariably, because the JIT was able to make optimizations mid-benchmark.
See: How do I write a correct micro-benchmark in Java?, What is going on in this java benchmark?, and Java benchmarking - why is the second loop faster? for some examples.
I have only ever read about the JIT and wish to prove it's existence as opposed to just believing in it like some sort of religious God.
This is an unnecessary line of thinking; there's a lot going on between your keyboard and your monitor that you've never noticed or don't understand. The JIT is documented behavior of the JVM, that's all you need to know. It's fine if you don't understand it and want to learn more, but it's not some mythical, ethereal construct.
JIT Just in Time compilation is a sort of pre compilation that is done prior of execution of byte code. From ORacle site:
"In theory, the JIT comes into use whenever a Java method is called,
and it compiles the bytecode of that method into native machine code,
thereby compiling it “just in time” to execute"
The most reliable effect of JIT is visible comparing java itself with and without jit.
JIT (Just In Time compilation) was introduced in java 1.2 so the best is to execute the same code with java 1.1 and java 1.2 and check the performances.
Prior to java 1.2 java was considered a very slow language and only after the introduction of JIT it has been extensively used in any field.
Instead is difficult to compare C++ or C and java. Potentially C++ is faster then java, because also with JIT java is an interpreted language. JIT compilation helps because the code that is executed more often is interpred only one time instead of each time it is executed.
Differences between java and C++ can involve how libraries are designed, presence or absence of certain primitive types, how code is compiled, level of optimizations, in case of java how gc is configured and so on.
Note that there can be differences also between java and java also with same jdk and same jvm depending on compilation parameters and execution parameters.
It is not possible to say that Java is faster than C or viceversa, too many parameters are involved in this kind of comparison. Sometime C++ is faster, sometime java is the best.
Here is a reference from Oracle on JIT compilation: http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/underst_jit.html

Hotspot JIT optimizations

In a lecture about JIT in Hotspot I want to give as many examples as possible of the specific optimizations that JIT performs.
I know just about "method inlining", but there should be much more. Give a vote for every example.
Well, you should scan Brian Goetz's articles for examples.
In brief, HotSpot can and will:
Inline methods
Join adjacent synchronized blocks on the same object
Eliminate locks if monitor is not reachable from other threads
Eliminate dead code (hence most of micro-benchmarks are senseless)
Drop memory write for non-volatile variables
Replace interface calls with direct method calls for methods only implemented once
et cetera
There is a great presentation on the optimizations used by modern JVMs on the Jikes RVM site:
ACACES’06 - Dynamic Compilation and Adaptive Optimization in Virtual Machines
It discusses architecture, tradeoffs, measurements and techniques. And names at least 20 things JVMs do to optimize the machine code.
I think the interesting stuff are those things that a conventional compiler can't do contrary to the JIT. Inlining methods, eliminating dead code, CSE, live analysis, etc. are all done by your average c++ compiler as well, nothing "special" here
But optimizing something based on optimistic assumptions and then deoptimizing later if they turn out to be wrong? (assuming a specific type, removing branches that will fail later anyhow if not done,..) Removing virtual calls if we can guarantee that there exists only one class at the moment (again something that only reliably works with deoptimization)? Adaptive optimization is I think the one thing that really distinguishes the JIT from your run of the mill c++ compiler.
Maybe also mention the runtime profiling done by the JIT to analyse which optimizations it should apply (not that unique anymore with all the profile-guided optimizations though).
There's an old but likely still valid overview in this article.
The highlights seem to be performing classical optimizations based on available runtime profiling information:
JITting "hot spots" into native code
Adaptive inlining – inlining the most commonly called implementations for a given method dispatch to avoid a huge code size
And some minor ones like generational GC which makes allocating short lived objects cheaper, and various other smaller optimizations, plus whatever else was added since that article was published.
There's also a more detailed official whitepaper, and a fairly nitty-gritty HotSpot Internals wiki page that lists how to write fast Java code that should let you extrapolate what use cases were optimized.
Jumps to equivalent native machine code instead of JVM interpretation of the op-codes. The lack of a need to simulate a machine (the JVM) in machine code for a heavily used part of a Java application (which is the equivalent of an extension of the JVM) provides a good speed increase.
Of course, that's most of what HotSpot is.

How to induce or help Java Compilers to optimize code?

I'm wondering which optimizations of Java Compilers can be usually blocked (or not detected) because of non-clear or badly written code, and what kind of commong mistakes are made that obfuscates the code for the Compiler
Please understand that modern runtime environments (the actual Java command) is not executing the java bytecodes naively one by one, but is doing very heavy processing to compile to actual machine code.
This means that there is no special reason to make the bytecode particularly smart or optimized, as the JRE gives the same results anyway. For mobile Java devices, where the interpreter is less smart, and memory constraints are present, the ProGuard system allows for quite a bit of optimizing transformations. You might find these interesting.
JIT compilers are typically optimized for common coding patterns and use cases. Your best bet is to adhere to common conventions, patterns, and idioms. Trying to "optimize code for the compiler" might result in code that is actually harder to optimize.
I would advice to just try to make your code clear and expressive, and let the compiler do its job.
... I wanted to know if there were very common mistakes that could be avoided with a bit more of attention when coding.
For Sun's HotSpot JVMs, the only mistake that you can make in the general sense is to try to do things in tricky ways (possibly) in the belief that it makes your code faster. It is best to just write simple code. I've seen this advice from someone senior in the HotSpot team.
Best practice is to leave optimization to the JIT compiler, and only attempt to micro-optimize if the profiler tells you that you have a problem.
(There are well know things you should avoid, like using exceptions for flow control, doing string concatenation in a loop, or trying to do your own memory management. But these are probably higher level than you are interested in.)

Jython Optimizations

Are their any ways to optimize Jython without resorting to profiling or significantly changing the code?
Specifically are there any flags that can be passed to the compiler, or code hints in tight loops.
No flags, no code hints. You can optimize by tweaking your code much as you would for any other Python implementation (hoisting, etc), but profiling helps by telling you where it's worth your while to expend such effort -- so, sure, you can optimize "without resorting to profiling" (and the code changes to do so may well be deemed to be not significant), but you're unlikely to guess right about where your time and energy are best spent, while profiling helps you determine exactly that.
Jython compiler does not offer lots of optimization choices. However, since the Java virtual machine (java) and perhaps compiler (javac) are getting invoked in the back end or at runtime, you should take a look at them.
Java has different runtime switches to use depending on whether you are going to launch it as a server process, client process, etc. You can also tell how much memory to allocate too.
I know this is an old question, but I'm just putting this for completeness.
You can use:-J-server flag to launch Jython in the Java server mode, which can help speed up the hot loops. (JVM will look to aggressively optimize, but might slow up the start up time)

Should I look at the bytecode that is produce by a java compiler?

No
The JIT compiler may "transform" the bytecode into something completely different anyway.
It will lead you to do premature optimization.
Yes
You do not know which method will be compiled by the JIT, so it is better if you optimize them all.
It will make you a better Java programmer.
I am asking without really knowing (obviously) so feel free to redirect to JIT hyperlinks.
Yes, but to a certain extent -- it's good as an educational opportunity to see what is going on under the hood, but probably should be done in moderation.
It can be a good thing, as looking at the bytecode may help in understanding how the Java source code will be compiled into Java bytecode. Also, it may give some ideas about what kind of optimizations will be performed by the compiler, and perhaps some limitations to the amount of optimization the compiler can perform.
For example, if a string concatenation is performed, javac will optimize the concatenation into using a StringBuilder and performing append methods to concatenate the Strings.
However, if the string concatenation is performed in a loop, a new StringBuilder may be instantiated on each iteration, leading to possible performance degradation compared to manually instantiating a StringBuilder outside the loop and only performing appends inside the loop.
On the issue of the JIT. The just-in-time compilation is going to be JVM implementation specific, so it's not very easy to find out what is actually happening to the bytecode when it is being converted to the native code, and furthermore, we can't tell which parts are being JITted (at least not without some JVM-specific tools to see what kind of JIT compilation is being performed -- I don't know any specifics in this area, so I am just speculating.)
That said, the JVM is going to execute the bytecode anyway, the way it is being executed is more or less opaque to the developer, and again, JVM-specific. There may be some performance tricks that one JVM performs while another doesn't.
When it comes down to the issue of looking at the bytecode generated, it comes down to learning what is actually happening to the source code when it is compiled to bytecode. Being able to see the kinds of optimizations performed by the compiler, but also understanding that there are limits to the way the compiler can perform optimizations.
All that said, I don't think it's a really good idea to become obsessive about the bytecode generation and trying to write programs that will emit the most optimized bytecode. What's more important is to write Java source code that is readable and maintainable by others.
That depends entirely on what you're trying to do. If you're trying to optimize a method/module, looking at the byte code is going to be a waste of your time. Always profile first to find where your bottlenecks are, then optimize the bottlenecks. If your bottleneck seems as tight as it possibly can be and you need to make it faster, you may have no choice but to rewrite that in native code and interface with JNI.
Trying to optimize the generated bytecode will be of little help, since the JIT compiler will do a lot of work, and you won't have much of an idea of exactly what it's doing.
I wouldn't think so. Short of having to debug the javac compiler or wanting to know as a matter of interest, I cannot think of one good reason why someone would care what bytecode gets generated.
Knowing bytecode won't make you a better Java programmer any more than knowing how an internal combustion engine works will make you a better driver.
Think in terms of abstractions. You don't need to know about the actions of quarks or atoms when trying to calculate the orbits of planets. To be a good Java programmer, you should probably learn ... um .. Java. Yes, Java, that's it :-)
Unless you're developing a high-capacity server of some sort, you'll likely never need to examine the bytecode, except out of curiosity. Source code that adheres to acceptable coding practices in your organization will provide ample performance for most applications.
Don't fret over performance until you've found issues after load-testing your application (or the entire customer service force lynches you for that screen that takes "forever" to load). Then, hammer away at the bottlenecks and leave the rest of the code alone.
Bytecode requires a modest learning curve to understand. Sure, it never hurts to learn more, but pragmatism suggests putting it off until it's necessary. (And should that moment come, I recommend finding someone to mentor you.)

Categories

Resources