[JVM Parsing series] [11] bytecode execution stack frame, how is your bytecode running?

Source: Internet
Author: User

In the previous chapters, we explained the memory allocation and management of the JVM, and the file structure of class was a bad line. So from the 11th chapter we begin to talk about how a Java virtual machine executes a class file.

First, we should make it clear that virtual machines are different from physical machines, and that the execution engine of a physical machine is built on the processor, hardware, and instruction set. And our virtual machines are implemented by ourselves. There are roughly two ways to perform in a virtual machine: Interpreting execution and compiling execution.

As we have said before, the virtual machine running method runs in the Java Virtual machine stack, inside the storage structure is the stack frame, need to know how a virtual machine runs bytecode file, first we need to understand the structure of a stack frame.

Stack frame:

stack frame as a substitute for a method (at execution time) it certainly needs to have all the characteristics of the method. The arguments and methods that we define in the method are not missing. This part is called the local variable table in the stack frame, second, each +-*/and the rest of the various assignments also need to occupy an area, this area is called the operand stack, in the process of running we may still call other methods, At this point we need a pointer-like reference to find the entrance to the method, but until all references in the JVM are implemented with symbolic references, we must also need a dynamically linked part to dynamically convert the symbolic reference to the memory address at run time. The rest of the return information corresponds to a method return address. so we get the following data structure, which becomes the stack frame .




Let's go through each section in more detail:





local Variable Table :

It is mainly used to store local variables defined by method parameters and methods internally. We have previously analyzed the method table, and the code attribute in the method table has a parameter that max_locals defines the maximum value of the local variable table that the method needs to allocate.

The local variable table uses the slot as the smallest unit. The JVM says a slot should be able to hold a Boolean, byte,char,short,int,float,reference,returnaddress type of data, so the slot does not have a fixed size, The length of the slots differs depending on the length of the data above. The above data type occupies 32 bits in the JVM, so the slot also occupies 32 bits. If you encounter a 64-bit data type slot, select allocate two contiguous slots in a high-alignment manner. Using an index to find slot,slot at execution time is also reusable because a slot may not occupy the entire life cycle of the method, but this reuse can affect the GC. Let's give an example:

public class Slotgctest {public static void main (string[] args) {//TODO auto-generated method stubbyte[] Holder = new BYT E[64*1024*1024]; System.GC ();}}
Using the above code for garbage collection should be consistent with our expectation that this 64mb of memory will not be recycled, as it can still be found through gcroot. The results of the output using the-VERBOSE:GC parameter are as follows:

[GC (System.GC ())  67502k->65976k (188416K), 0.0007246 secs][full GC (System.GC ())  65976k->65811k ( 188416K), 0.0039451 secs]
But do we put the GC code out of the way?

public class Slotgctest {public static void main (string[] args) {//TODO auto-generated method Stub{system.out.println ("construct code block "); byte[] holder = new byte[64*1024*1024];} System.out.println ("main"); System.GC ();}}

As we can see from the above code, the location of our GC has been constructed outside the code block, gcroot should not find holder, this 64mb of memory will be recycled. The output is as follows:

Construct code block MAIN[GC (System.GC ())  67502k->65928k (188416K), 0.0018770 secs][full GC (System.GC ())  65928k-> 65811K (188416K), 0.0057137 secs]
Did I ask you to be blind? Why is it still not recycled? This is how slot multiplexing affects the GC, and we add a little bit of code

public class Slotgctest {public static void main (string[] args) {//TODO auto-generated method Stub{system.out.println ("construct code block "); byte[] holder = new byte[64*1024*1024];} int a = 0; System.out.println ("main"); System.GC ();}}
We only added int a = 0; this line of code. The final output is as follows:

Construct code block MAIN[GC (System.GC ())  67502k->65992k (188416K), 0.0011489 secs][full GC (System.GC ())  65992k-> 275K (188416K), 0.0038030 secs]
You'll find that it's actually recycled in the full GC. This is because although the 64MB slot has left the scope but the slot is not overwritten, the local variable table in gcroot still holds the holder association. So we have an empty argument that Holder = null;

When we generate a class variable, it is first assigned at the preparation stage, and the second assignment at initialization time so that the class variable is directly int a without assigning a value is possible.

If the local variable is not assigned a value, the result is as follows:


The local variable will not be assigned a value error.




Operand stack :

The operand stack is a standard stack, followed by the first-in and out-of-the-way principle, and the same as the previous parameter, the local variable table, its stack depth also needs to exist in the Max_stacks data phase of the code attribute, the elements of the operand stack can be any Java data type. Let's take an example a++, which is done in the stack.





Dynamic Links :

Links are divided into two types, static links and dynamic links, in the compilation period, the runtime is static link, the main has the Statics method, the private method, the instance constructor and the parent class method. Dynamic link because it is not possible to determine the specific invocation of the method address, so often to be executed to be converted into memory, about the specific content of the dynamic link because of the length of the problem we will say separately.




method return address :

The end of a method is only two cases, one is return (or executed), the other is encountered an exception, and throw out. After a method is finished, it is necessary to return the location of the previously called method, so we need to log some information to store the execution state of the call location. In general, when this method is finished, the stack frame of the calling method is resumed, and the return value is pressed into the operand stack (if any), and finally the pc+1.

[JVM Parsing series] [11] bytecode execution stack frame, how is your bytecode running?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.