https://www.quora.com/In-Java-what-exactly-will-the-JVM-interpreter-and-the-JIT-compiler-do-with-the-bytecode
The Just-In-Time (JIT) compiler is a component of the Java™ Runtime Environment that improves the performance of Java applications at run time.
Java programs consists of classes, which contain platform-neutral bytecodes that can be interpreted by a JVM on many different computer architectures. At run time, the JVM loads the class files, determines the semantics of each individual bytecode, and performs the appropriate computation. The additional processor and memory usage during interpretation means that a Java application performs more slowly than a native application. The JIT compiler helps improve the performance of Java programs by compiling bytecodes into native machine code at run time.
The JIT compiler is enabled by default, and is activated when a Java method is called. The JIT compiler compiles the bytecodes of that method into native machine code, compiling it "just in time" to run. When a method has been compiled, the JVM calls the compiled code of that method directly instead of interpreting it. Theoretically, if compilation did not require processor time and memory usage, compiling every method could allow the speed of the Java program to approach that of a native application.
JIT compilation does require processor time and memory usage. When the JVM first starts up, thousands of methods are called. Compiling all of these methods can significantly affect startup time, even if the program eventually achieves very good peak performance.
In practice, methods are not compiled the first time they are called. For each method, the JVM maintains a call count, which is incremented every time the method is called. The JVM interprets a method until its call count exceeds a JIT compilation threshold. Therefore, often-used methods are compiled soon after the JVM has started, and less-used methods are compiled much later, or not at all. The JIT compilation threshold helps the JVM start quickly and still have improved performance. The threshold has been carefully selected to obtain an optimal balance between startup times and long term performance.
After a method is compiled, its call count is reset to zero and subsequent calls to the method continue to increment its count. When the call count of a method reaches a JIT recompilation threshold, the JIT compiler compiles it a second time, applying a larger selection of optimizations than on the previous compilation. This process is repeated until the maximum optimization level is reached. The busiest methods of a Java program are always optimized most aggressively, maximizing the performance benefits of using the JIT compiler. The JIT compiler can also measure operational data at run time, and use that data to improve the quality of further recompilations.
The JIT compiler can be disabled, in which case the entire Java program will be interpreted. Disabling the JIT compiler is not recommended except to diagnose or work around JIT compilation problems.
I read a lot about Java in the last week, so I hope I can answer this as simply as I can.
For a complied language, everything is converted into '0's and '1's, or binary, if you will. Because the computer only understands binary. Binary strings can be converted to hexadecimal strings by using converting four binary digits to a one hexadecimal digit, and padding the binary string with zeroes on the left if need be. Execution of a complied program is essentially faster, because the computer knows which sequence of digits belong to what operation, and the operations that are performed are almost always optimized to run as fast as possible.
On the other hand, in interpreted languages, each statement is parsed (humans read a sentence and understand what it means, computers parse it) before it is executed. This produces a substantial overhead as each statement has to be parsed every time the program is executed.
Java implements a combination of both of these. It compiles the program into bytecode. The JVM interprets the bytecode and performs the operations. So basically, we have a combination of both, compilation, and interpretation.
Moving on to your question, if you open a .class file that is compiled from a .java file, you'll be able to see lots of hexadecimal strings. That is the output of the compilation for the JVM. Now, JVM reads each string one by one, deduces what it means, decides what operations to perform, and then performs the operations. It does this every time it .class file is run. If it was actually compiled to machine code, it wouldn't need to deduce what each string meant, it would just have to perform the operations because they would be mentioned directly.
Enough technical talk, let's work with an easier example.
You are living in a country where people speak several dialects. You speak all of these dialects. That's machine language. Each processor has it's own machine language.
Some alien speaks a language Java, no one else does. The alien wants to communicate with the citizens of your country. Maybe it needs help rebuilding it's ship so it can go back home.
Somehow, you managed to invent a device that converts the alien's language, Java, into another dialect: bytecode. You are the only person that understands bytecode. You are named JVM by everyone else.
Now, when the alien wants to communicate, it translates what it wants to say to bytecode. You read the bytecode, you understand what it means. But citizens of your country don't, and each of them speaks a different dialect. There's no way you could talk to all of them using a single language. So, each time the aliens sends some bytecode and you understand it, you have to read each string of the message to translate it into the dialect that a person who is capable of performing the task understands. This way, Java is able to be a platform-independent language. You, the JVM, is present on every computer that has the Java Runtime Engine (JRE) installed. Each computer speaks a different dialect. Your job is to translate the bytecode into each computer's machine language. You'll have to do this every time, because that is one trade off for achieving platform independence.
The Just-In-Time (JIT) compiler is a component of the Java™ Runtime Environment that improves the performance of Java applications at run time.
Java programs consists of classes, which contain platform-neutral bytecodes that can be interpreted by a JVM on many different computer architectures. At run time, the JVM loads the class files, determines the semantics of each individual bytecode, and performs the appropriate computation. The additional processor and memory usage during interpretation means that a Java application performs more slowly than a native application. The JIT compiler helps improve the performance of Java programs by compiling bytecodes into native machine code at run time.
The JIT compiler is enabled by default, and is activated when a Java method is called. The JIT compiler compiles the bytecodes of that method into native machine code, compiling it "just in time" to run. When a method has been compiled, the JVM calls the compiled code of that method directly instead of interpreting it. Theoretically, if compilation did not require processor time and memory usage, compiling every method could allow the speed of the Java program to approach that of a native application.
JIT compilation does require processor time and memory usage. When the JVM first starts up, thousands of methods are called. Compiling all of these methods can significantly affect startup time, even if the program eventually achieves very good peak performance.
In practice, methods are not compiled the first time they are called. For each method, the JVM maintains a call count, which is incremented every time the method is called. The JVM interprets a method until its call count exceeds a JIT compilation threshold. Therefore, often-used methods are compiled soon after the JVM has started, and less-used methods are compiled much later, or not at all. The JIT compilation threshold helps the JVM start quickly and still have improved performance. The threshold has been carefully selected to obtain an optimal balance between startup times and long term performance.
After a method is compiled, its call count is reset to zero and subsequent calls to the method continue to increment its count. When the call count of a method reaches a JIT recompilation threshold, the JIT compiler compiles it a second time, applying a larger selection of optimizations than on the previous compilation. This process is repeated until the maximum optimization level is reached. The busiest methods of a Java program are always optimized most aggressively, maximizing the performance benefits of using the JIT compiler. The JIT compiler can also measure operational data at run time, and use that data to improve the quality of further recompilations.
The JIT compiler can be disabled, in which case the entire Java program will be interpreted. Disabling the JIT compiler is not recommended except to diagnose or work around JIT compilation problems.
I read a lot about Java in the last week, so I hope I can answer this as simply as I can.
For a complied language, everything is converted into '0's and '1's, or binary, if you will. Because the computer only understands binary. Binary strings can be converted to hexadecimal strings by using converting four binary digits to a one hexadecimal digit, and padding the binary string with zeroes on the left if need be. Execution of a complied program is essentially faster, because the computer knows which sequence of digits belong to what operation, and the operations that are performed are almost always optimized to run as fast as possible.
On the other hand, in interpreted languages, each statement is parsed (humans read a sentence and understand what it means, computers parse it) before it is executed. This produces a substantial overhead as each statement has to be parsed every time the program is executed.
Java implements a combination of both of these. It compiles the program into bytecode. The JVM interprets the bytecode and performs the operations. So basically, we have a combination of both, compilation, and interpretation.
Moving on to your question, if you open a .class file that is compiled from a .java file, you'll be able to see lots of hexadecimal strings. That is the output of the compilation for the JVM. Now, JVM reads each string one by one, deduces what it means, decides what operations to perform, and then performs the operations. It does this every time it .class file is run. If it was actually compiled to machine code, it wouldn't need to deduce what each string meant, it would just have to perform the operations because they would be mentioned directly.
Enough technical talk, let's work with an easier example.
You are living in a country where people speak several dialects. You speak all of these dialects. That's machine language. Each processor has it's own machine language.
Some alien speaks a language Java, no one else does. The alien wants to communicate with the citizens of your country. Maybe it needs help rebuilding it's ship so it can go back home.
Somehow, you managed to invent a device that converts the alien's language, Java, into another dialect: bytecode. You are the only person that understands bytecode. You are named JVM by everyone else.
Now, when the alien wants to communicate, it translates what it wants to say to bytecode. You read the bytecode, you understand what it means. But citizens of your country don't, and each of them speaks a different dialect. There's no way you could talk to all of them using a single language. So, each time the aliens sends some bytecode and you understand it, you have to read each string of the message to translate it into the dialect that a person who is capable of performing the task understands. This way, Java is able to be a platform-independent language. You, the JVM, is present on every computer that has the Java Runtime Engine (JRE) installed. Each computer speaks a different dialect. Your job is to translate the bytecode into each computer's machine language. You'll have to do this every time, because that is one trade off for achieving platform independence.
Комментариев нет:
Отправить комментарий