Bytecode prevents memory errors and improves code quality
Translation: Cheramiemail: cherami@163.net
Start using Java
Most Java programmers know that their procedures are usually not compiled as a native code but is compiled into a byte format performed by Java Virtual Machine (JVM). However, there are few Java programmers have seen by node code because their tools do not encourage them to see. Most Java debugging tools do not allow single-step execution bytes, they either display source lines, or nothing is also displayed. Fortunately, JDK provides Java, a command line tool, which makes the viewing byte code easy. Let us look at an example:
Public class bytecodedemo {public static void main (string [] args) {system.out.println ("Hello World");}}
After compiling this class, you can open the .class file with the hex editor and then refer to the virtual machine specification to translate the word code. Fortunately is a simpler method. JDK contains a command line reverse editor: javap, which converts the bytecode as a readable macrper, which can get the '-C' parameter to get the bytecode list by passing the '-C' parameter:
Javap -c bytecodedemo
You should see the output like this:
public class ByteCodeDemo extends java.lang.Object {public ByteCodeDemo (); public static void main (java.lang.String []);} Method ByteCodeDemo () 0 aload_0 1 invokespecial # 1
Just from this short list you can learn a lot of information. Starting from the first instruction from the MAIN method:
0 getStatic # 2
After the first instruction is analyzed, it is easy to guess the meaning of other instructions. The 'LDC' (Load Constant) instruction presses the constant "Hello, World." into the operator count. The 'Invokevirtual' instruction calls the PrintLn method, which pops its two parameters from the operator stack. Don't forget that there are two parameters such as Println: the string above, plus hidden 'this' reference. Word: How to prevent memory errors
Java language is often touted to develop the "secure" language of the Internet software. How to reflect security on the surface and C so similar code? An important security concept it introduced is to prevent memory-related errors. Computer criminals use memory errors to insert their malicious code in other situations. The Java Biode code is the first example to prevent this attack, like the example below:
Public float add (float f, int N) {RETURN F N;}
If you add this method to the example above, recompile it, then run Javap, you will see the byte size similar to this:
Method float add (float, int) 0 fload_1 1 iLoad_2 2 i2f 3 fadd 4 freturn
At the beginning of the method, the virtual machine puts the parameters of the method into a data structure called a local variable table. Like the name, the local variable table also contains any local variables you declare. In this example, the method begins with the items of three local variables, which are parameters of the ADD method, and the position 0 saves the THIS reference, and the positions 1 and 2 save the FLOAT and INT parameters, respectively.
To actually operate these variables, they must be loaded (press) to the operator stack. The first command fload_1 presses the FLOAT at position 1 into the operator count, the second instruction iLoad_2 presses the INT of the position 2 into the operator count stack. One of these instructions is a payment of the 'i' and 'F' prefix in the instruction, which means that the Java bytecode instruction is stronger. If the type of parameters and the type of bytecode do not match, the VM refuses this byte code as unsafe. More preferably, the bytecode is designed to perform such a type of security check at the class when the class is loaded.
How is this type of security to strengthen security? If an attacker can deceive the virtual machine to use Int as a float or instead, it can easily destroy the calculation with a expected method. If these calculations involve bank balance, then hidden security is obvious. More dangerous is deceived VM to reference an int as an Object reference. In most cases, this will cause the VM crash, but the attacker only needs to find a vulnerability. Don't forget that an attacker does not manually search this vulnerability - writing a program that generates billions of misunderstandings is quite easy, these arrangements try to find the lucky VM.
Another memory security for the bytecode is an array operation. 'Aastore' and 'Aaload' bytecato operation Java array and they always check array boundaries. If the calling program has passed the array, these bytes will throw an ArrayIndexoutofboundSexception. Perhaps all of the most important inspections use branch instructions, for example, bytecodes starting with IF. In the bytecode, the branch instruction can only be transferred to other instructions in the same method. The unique control that can be delivered outside the method is to return it: throw an exception or perform a 'Invoke' instruction. This not only closes a lot of attacks, but also prevents disgusting errors caused by swaying referen or stack conflicts. If you have used the system debugger to open your program and locate a random location in your code, you will be familiar with these errors. It is important to remember in all of these inspections that they are made by virtual machines in bytecode level rather than just in the source code level. A compiler such as a language such as C may prevent some memory errors discussed above when compiling, but these protection is just in the source code level. The operating system will be happy to load the execution of any machine code, regardless of these code generated by a fine C compiler or is generated by a malicious attacker. Simply put, C is just the top-oriented characteristics of the Java to the object to be extended to the compiled code level.
Analysis by node code improve code quality
The memory and security of Java bytecodes are all exist, so why do we pay attention to the word code? In many cases, you know how the compiler converts your code into a byte code to help you write more efficient code, and in some cases you can prevent unusual impossible errors. Consider the following example:
/ / Return Str1 Str2 String String Concat (String Str1, String Str2) {RETURN STR1 STR2;} // Attach STR2 to Str1 Void Concat (StringBuffer Str1, String Str2) {str1.append (str2);}
Guess how many methods are needed for each method. Now compiling these methods and run javap, you will get the output similar to the following:
Method Java.lang.String Concat1 (java.lang.string, java.lang.string) 0 new # 5
Method void concat2 (java.lang.stringbuffer, java.lang.string) 0 aload_1 1 aload_2 2 invokevirtual # 7
The Concat1 method performs five ways to call S: New, InvokeSpecial, and Three InvokeVirtuals, which is more work than the Concat2 method, the latter only executes an InvokeVirtual call. Most Java programmers have got a warning because string is not variable, and the string connection is more efficient using StringBuffer. This makes this very vivid using JavaP to analyze this. If you can't affirm that both language constructs are equal in performance, you should use JavaP to analyze bytecode. However, be careful about the Just-IN-TIME (JIT) compiler, because the JIT compiler recombinates the bytecode to the native code to perform some Java's unveiled additional optimization. Unless you have the source code of your virtual machine, you should add a reference performance analysis of your bytecode. One of the final examples show how to check the bytecode to help prevent errors in the program. Create two classes as below to ensure they in separate files.
Public class changeload {public static final boolean debug = false; public static boolean log = false;}
public class EternallyConstant {public static void main (String [] args) {System.out.println ( "EternallyConstant beginning execution"); if (ChangeALot.debug) System.out.println ( "Debug mode is on"); if ( ChangeaT.log) System.out.println ("Logging Mode Is On");}} If you run EternalLyConstant, you will get information:
ETERNALLYCONSTANT BEGINNING Execution.
Now try to edit ChangeAlot, modify the value of debug and log variables (two all True). Only recompile ChangeAlot. Run EternalLyconStant again, you will see the output below:
What happened to ETERNALLYCONSTANT BEGINNING EXECUTION logging mode is on debug? Even if you set the debug to true, the information "debug mode is on" did not appear. The answer is in the bytecode. Running javap for EternalLyConstant You will see:
Method vid main (java.lang.string "0 getStatic # 2
Bytecodes and VMs are quite complicated, which has exceeded this tip to cover the range. To know more, see "Inside the Java Virtual Machine" written by Bill Venners (Translator Note: http://www.Artima.com/insidejvm/ed2/ There is a book 1, 2, 3, 4, Free HTML version of 5, 7, 8, 9 and 20, English.)