编程知识 cdmana.com

Java JVM -- 5. Java virtual machine stack

Virtual machine stack Overview

   Because of the cross platform design ,Java The instructions of are designed according to the stack . Different platforms CPU The architecture is different , So it can't be designed based on registers .  The advantage of stack implementation is cross platform , Instruction set is small , Compiler easy to implement , The disadvantage is that the efficiency is reduced , More instructions are needed to implement the same function .

   Quite a few Java As soon as the developer mentioned Java Memory structure , It will be very rough to JVM The memory area in is interpreted as having only Java Pile up (heap) and Java Stack (stack), This division is directly inherited from the traditional C、C++ The memory layout structure of a program , stay Java The language seems a little rough , The actual partitioning of memory is more complicated than this .

First of all, we need to be clear about :

   Stack is the unit of execution , And the heap is the unit of storage .

    * Stack solves the problem of program execution , That is, how the program runs , Or how to deal with data .

    * Heap is to solve the problem of data storage , That is, how to put the data , Where to put it .

Java What is the virtual machine stack

  Java Virtual machine stack (Java Virtual Machine Stack), The early days were also called Java Stack . Each thread creates a virtual machine stack at the time of creation , It stores stack frames one by one (Stack Frame), Corresponding to time and again Java Method calls .

   Stack frame (Stack Frame) Used to store regional variable tables 、 Arithmetic unit stack 、 Dynamic connection 、 Method returns address and other information . The process of each method being called to the end of execution corresponds to the process of a stack frame from stack entry to stack exit in the virtual machine stack .

Life cycle

   Same as program counter Java Virtual machine stack (Java Virtual Machine Stack) It's also thread private , It has the same lifecycle as the thread .

effect

   executive director Java Program execution , It stores the local variables of the method 、 Part of the result , And participate in the call and return of methods .

Regional variables , It is compared to member variables ( Or property ).

Master data type variable VS Reference type variable ( Class 、 Array 、 Interface ).

Stack features

   Stack is a fast and efficient way to allocate storage , Access speed is only second to program counter .JVM Directly Java There are only two stack operations :

    ①  Each method performs , Along with the stack ( Into the stack 、 Pressing stack ).
    ②  After the implementation of the stack work .

   There is no garbage collection problem for the stack ( Stack overflow exists ).

  Virtual machine stack

Exception about stack

  Java The virtual machine specification allows Java The size of the stack is dynamic or fixed .

   If you use a fixed size Java Virtual machine stack , That's for every thread Java The capacity of virtual machine stack can be selected independently when the online program is established . If the thread requests to allocate more stack capacity than Java The maximum capacity allowed by the virtual machine stack ,Java The virtual machine will throw a StackOverflowError Abnormal ( Stack overflow ).

   If Java Virtual machine stack can dynamically expand Suite , And can't request enough memory when trying to expand the package , Or when creating a new thread, there is not enough memory to create the corresponding virtual machine stack , that Java The virtual machine will throw a outOfMemoryError Abnormal ( Memory overflow ).

We can test :

public class StackErrorTest {    private static int count = 1;    public static void main(String[] args) {        System.out.println(count++);        main(args);    }}

Execution results :

   When the stack depth reaches 15419 When , There is a shortage of stack memory space .

Set the stack memory size  

   We can use arguments -Xss Option to set the maximum stack space for threads , The stack size directly determines the maximum depth of function call .

Example :

   Set the stack size to 1MB:-Xss1m.

   Set the stack size to 1KB:-Xss1k.

Eclise in , Sets the stack memory size for the current class :

   Right click in the code area --> Run As -- >RunConfigurations --> On the left, select the class you want to set --> Right click Arguments Options --> VM arguments Argument settings --> And then Apply --> Run.

   Scope : It only works on this project .

Eclipse in , Set stack memory size for global :

   Menu bar Window --> preference --> Java --> Installed JREs --> Select the current package --> Edit --> Default VM Arguments Argument settings --> Finish.

   Scope : It works for all projects .

The storage unit of a stack

   Each thread has its own stack , All the data in the stack is in stack frame (Stack Frame) The format of exists .

   Each method running on a thread corresponds to a stack frame (Stack Frame).

   Stack frame is a memory block , It's a data set , It maintains all kinds of data information in the process of method execution .

What's on the stack ?

   Each thread has its own stack , All the data in the stack is in stack frame (Stack Frame) The format of exists . Each method being executed on this thread corresponds to a stack frame (Stack Frame). Stack frame is a memory block , It's a data set , It maintains all kinds of data information in the process of method execution .

  JVM Directly Java There are only two stack operations , It is the stack pressing and stack out of the stack frame , follow “ First in first out ”/“ Last in, first out ” Principles .

   In an activity thread , At one point in time , There will only be one active stack frame . That is, only the stack frame of the currently executing method ( Top stack frame ) It works , This stack frame is called the current stack frame (Current Frame), The method corresponding to the current stack frame is the current method (Current Method), The class that defines this method is the current class (Current Class).

   All bit group code instructions executed by the execution engine operate only on the current stack frame .

   If other methods are called in this method , The corresponding new stack frame will be created , At the top of the stack , Become the new current frame .

How the stack works

   Stack frames contained in different threads are not allowed to refer to each other , That is, it is impossible to refer to another thread's stack frame in one stack frame .

   If the current method calls another method , Method return , The current stack frame will return the execution result of this method to the previous stack frame , Then , The virtual machine discards the current stack frame , Make the previous stack frame become the current stack frame again .

  Java Method has two ways to return a function , One is normal function return , Use return Instructions ; The other is throw exception . Either way , Will cause the stack frame to pop up .

Stack memory structure

Each stack frame stores :

   Regional variable table (Local Variables)

   Arithmetic unit stack (operand Stack)( Or express stack )

   Dynamic link (DynamicLinking)( Or a method reference to the execution time constant pool )

   Method return address (Return Address)( Or method normal exit or abnormal exit definition )

   Some additional information

   In parallel, the stack under each thread is private , So each thread has its own stack , And there are many stack frames in each stack , The size of stack frame is mainly determined by the regional variable table and The stack of operands determines .

Regional variable table

   Regional variable table (Local Variables), It's called a local variable array or a local variable table .

   Defined as a digital array , It is mainly used to store method arguments and local variables defined in the method body. These data types include various basic data types 、 Object reference (reference), as well as returnAddress Type .

   Because the culture variable table is built on the stack of the program , Is the private data of the thread , So there is no data security problem .

   The required capacity of the culture variable table is determined at compile time , And store the method Code Attribute maximum local variables In the data item . It does not change the size of the culture variable table during method execution .

   The number of method nested calls depends on the size of the stack . In general , The bigger the stack , The more method nested calls there are . For a function , The more arguments and regional variables it has , Make the regional variable table expand , The bigger the stack frame is , In order to meet the increasing demand of information transmission . In turn, function calls will take up more stack space , As a result, the number of nested calls will be reduced .

   Variables in the culture variables table are only valid in the current method call . At method execution time , Through the use of regional variable table, the virtual machine completes the process of transferring the index value to the argument variable list . When the method call ends , With the destruction of method stack frame , The regional variable table will also be destroyed .

Variable slot (Slot)

   The index value is always stored in the local variable array index 0 Start , To array length -1 End of index .

   The basic storage unit of a regional variable table is Slot( Variable slot ), The culture variable table stores various basic data types known at compile time (8 Species ), Reference type (reference),returnAddress Variable of type .

   In the regional variable table ,32 Types within bits occupy only one slot( Include returnAddress Type ),64 The type of bit (long and double) Take two slot.

  byte、short、char Before being converted to int,boolean Also converted to int,0 Express false, Not 0 Express true.long and double It takes up two slot.

  JVM Will be for each of the culture variable tables Slot All assigned an access index , Through this index, you can successfully access the culture variable values specified in the culture variable table , When an instance method is called , Its method arguments and local variables defined inside the method body are copied to each of the region variables table in order slot On , If you need to access one of the culture variable tables 64 bit When the regional variation of , Just use the previous index ( such as : Visit long or double Type variable ).

Table of regional variables for common methods

   If the current frame is created by the construction method or example method , Then the object references this It will be stored in index For 0 Of Slot Place , The rest of the arguments continue in the order of the argument table .

( A method of construction or ) The regional variable table of the example method

The reuse of variable slots

   The slots in the culture variable table in the stack frame can be reused , If a regional variable goes beyond its scope , The new culture change declared after its scope is likely to reuse the slot of the expired culture variable , So as to save resources .

The comparison between static variables and regional variables

The classification of variables :

*  By data type : Basic data type 、 Reference type .

* According to the position declared in the class : Member variable ( Class variable , Example variable )、 Regional variables .

* Class variable :linking Of paper Stage , Assign values to class variables by default ,init Stage to assign values to class variables , Static code blocks .

* Example variable : With the object created , The instance variable space is allocated in heap space , And make default assignment .

* Regional variables : An explicit assignment must be made before use , Otherwise, the compilation will not pass .

   After the argument table has been allocated , According to the order and scope of the variables defined in the method body .

   We know that class variable table has two initialization opportunities , For the first time “ Preparation stage ”, Perform system initialization , Set zero to the class variable , The other was in “ initialization ” Stage , Give the programmer an initial value defined in the code .

   Unlike class variable initialization , There is no system initialization process for the regional variable table , This means that once a local variable is defined, it must be artificially initialized , Otherwise, it cannot be used .

   In stack frame , The most closely related part to performance tuning is the previously mentioned regional variable table . At method execution time , The virtual machine uses the culture variable table to complete the transfer of methods .

   Variables in the regional variable table are also important garbage collection root nodes , Objects that are directly or indirectly referenced in the culture variable table will not be recycled .

Arithmetic unit stack

   Arithmetic unit stack (Operand Stack), Each independent stack frame contains a list of regional variables , It also includes a last in, first out (Last-In-First-Out) Operation element stack of , It can also be called Expression stack (Expression Stack).

summary

   Arithmetic unit stack , During method execution , According to the bit group code instruction , To write or extract data from a stack , That's the stack (push) and Out of the stack (pop).

   Some bit group code instructions push values into the operand stack , The rest of the bit group code instructions take the operands out of the stack , Use them and then push the results onto the stack . such as : Perform replication 、 Exchange 、 Sum and so on .

Summation instruction

Code examples :

   Arithmetic unit stack , It is mainly used to store the intermediate results of the calculation process , At the same time, it is used as a temporary storage space for variables in the calculation process .

   The arithmetic unit stack is JVM A workspace where the engine is executed , When a method is first executed , A new stack frame will also be created , The algorithm stack of this method is empty . Be careful : At this point, the array has a length , Because once the array is set up , Then it is immutable .

   Each element stack has a specific stack depth for storing values , The maximum depth required is defined at compile time , Stored in method Code Property named maxstack Of .

   Any element in the stack can be arbitrary Java Data type :

     32bit The type of the type occupies a stack unit depth .

     64bit The type of takes up two stack units of depth .

   The operation element stack does not access data by accessing index , But only through the standard stack in and stack out operations to complete a data access . If the called method has a return value , Its return value will be pushed into the stack of operands in the current stack frame , And update PC The next bit group code instruction to be executed in the register .

   The data type of the element in the operand stack must strictly match the sequence of the bitgroup code instruction , This is verified by the compiler during the compiler , At the same time, in the class loading process, the data flow analysis phase of the class verification phase needs to be verified again .

   in addition , We said Java The interpretation engine of a virtual machine is a stack based execution engine , The stack refers to the stack of operands .

Code tracing

Let's write a piece of code first :

public void testAddOperation() {    byte i = 15;    int j = 8;    int k = i + j;}

Use javap command (javap -v Class name .class) Decompilation class Archives :

byte、short、char、boolean It's all used inside int For storage .

From the code above, we can know that , We all go through bipush For operands 15 and 8 Do stack operation

At the same time iadd Method to add ,i It stands for int, That is to say int Type addition operation

The execution process is as follows :

   First execute the first statement ,PC The register points to 0, That is, the instruction address is 0, Then use bipush Let the operands 15 Into the stack .

   After execution , Let PC + 1, Point to the next line of code , The next line of code is to store the elements of the operator stack in the regional variable table 1 The location of , We can see that an element has been added to the list of regional variables :

Why is the culture variable table not from 0 At the beginning ?

   In fact, the regional variable table is also derived from 0 Starting , But because 0 It's stored in position 1 this Indicators , So we just omit .

   And then PC+1, It points to the next line . Let the operands 8 Also into the stack , Simultaneous execution store operation , Put it in the regional variable table :

   And then from the regional variable table , Put the data in the stack of operands in turn :

   Then add the two elements in the stack , And stored in the regional variable table 3 The location of :

   Finally PC The location of the register points to 10, That is to say return Method , Then exit the method directly .

Top of stack caching

Top of stack caching :Top Of Stack Cashing.

   Mentioned earlier , Stack based virtual machines use more compact zero address instructions , But when completing an operation, it is necessary to use more stack in and out instructions , This also means that more instruction dispatch will be required (instruction dispatch) Times and memory reads / Write times .

   Since the operands are stored in memory , So frequent memory reads / Write operations will inevitably affect the speed of execution . To solve this problem ,HotSpot JVM The top of stack cache was proposed by designers of (Tos,Top-of-Stack Cashing) Technology , Cache all stack top elements in physics CPU In the register of , In order to reduce the read to memory / Write times , Improve the efficiency of the execution engine .

Based on the register architecture : Fewer instructions , Fast execution .

Dynamic link

Dynamic link 、 Method return address 、 Additional information : These areas are called frame data areas in some places .

   Dynamic link :Dynamic Linking. Each stack frame contains a reference to the method of the stack frame in the execution time constant pool , The purpose of including this reference is to support the dynamic linking of the code of the current method (Dynamic Linking). such as :invokedynamic Instructions .

   stay Java When the original file is compiled into the bitgroup code file , All variables and method references are referred to as symbols (symbolic Reference) Store in class In the constant pool of files .

   such as : Describe when a method calls another method , Is represented by a symbolic reference to a method in a constant pool , So the function of dynamic linking is to convert these symbolic references into direct references of calling methods .

Why the pool of runtime constants is needed ?

   Because in different ways , Can call the same constant or method , So just store one copy , Save space . The function of constant pool is to provide some symbols and constants , For the identification of instructions .

Method calls : Analysis and distribution

   stay JVM in , Converting a symbolic reference to a calling method's direct reference is related to the binding mechanism of the method .

Link to

Static links

   When a bit group code file is loaded into JVM Inside , If the called target method is known at compile time , And the execution period remains unchanged , In this case, the process of converting the symbolic reference of the descending calling method into a direct reference is called a static link .

Dynamic link

   If the called method cannot be determined at compile time , That is to say , The symbol of the called method can only be converted to a direct reference during program execution , Because of the dynamic nature of this reference conversion process , So it's also called dynamic linking .

Binding mechanism

   The binding mechanism of linking the corresponding method is : Early tying (Early Binding) It's tied to the late stage (Late Binding). Binding is a field 、 Methods or classes are replaced by direct references in symbolic references , It only happened once .

Early tying

   Early binding refers to the target method called if known at compile time , And the execution period remains unchanged , You can bind this method to the type it belongs to , In this way , Because it is clear which target method is called , Therefore, we can use static linking to convert symbolic reference to direct reference .

The late stage of the knot

   If the called method cannot be determined at compile time , You can only bind related methods according to the actual type during program execution , This kind of binding is also called late binding .

Virtual methods and non virtual methods

   If the method determines the specific call version at compile time , This version is immutable at execution time , Such methods are called non virtual methods .

   Static method 、 Private method 、fina1 Method 、 Example constructor 、 Parent methods are all non virtual methods .

   Other methods are called virtual methods .

The premise of using subtypes of subclass objects :

  • Class inheritance relationship

  • Method rewriting

The virtual machine provides the following method call instructions :

Normal call command :

    • invokestatic: Call static method , The parsing phase determines the unique method version .

    • invokespecial: call <init> Method 、 Private and superclass methods , The parsing phase determines the unique method version .

    • invokevirtual: Call all virtual methods .

    • invokeinterface: Call interface method .

Dynamic call command :

    • invokedynamic: Dynamically resolve the method to be called , Then execute

   The first four instructions are embedded in the virtual machine , The call execution of method cannot be interfered by human beings , and invokedynamic The command supports the user to determine the method version . among invokestatic Instructions and invokespecial Methods that are not virtual calls are called , The rest (fina1 Except for embellishment ) It's called virtual method .

invokednamic Instructions

  JVM Bit group code instruction set has been relatively stable , Until Java7 It's just added a new one invokedynamic Instructions , This is Java In order to achieve 『 Dynamic type language 』 An improvement made with support .

   But in Java7 Direct generation is not provided in invokedynamic Method of instruction , Need help ASM This low-level bit group coding tool is used to generate invokedynamic Instructions . until Java8 Of Lambda The appearance of expressions ,invokedynamic Generation of instructions , stay Java There is a direct way to generate .

  Java7 The nature of the dynamic language type support added in is to Java Modification of the virtual machine specification , Not right Java Modification of language rules , This one is relatively complicated , Added method call in virtual machine , The most direct beneficiary is execution Java The compiler of the platform's dynamic language .

Dynamic type language and static type language

   The difference between a dynamic type language and a static type language lies in : Whether the type is checked at compile time or at run time , Satisfying the former is a static type language , Instead, it's a dynamic type language .

   To put it bluntly, it is , Static type language is to judge the type information of a variable itself ; Dynamic type language is the type information that determines the value of a variable , Variable has no type information , Variable value is the only way to get type information , This is an important feature of dynamic languages .

Java:String info = "mogu blog"; (Java It's static type language , Type checking will be performed after compiling )

JS:var name = "shkstart"; var name = 10; (JS It's dynamic language , Only when the inspection is carried out )

The nature of method rewriting

Java The essence of method rewriting in language :

   Find the actual type of the object executed by the first element at the top of the stack , Notes C.

   If in type C And the description in constant 、 Simple names match the method , Then check the access permission , If passed, return the direct reference of this method , End of query ; If not , Then return to java.lang.IllegalAccessError Abnormal .

   Otherwise , According to the inheritance relationship from the bottom to the top C Each parent class of 2 Step by step search and verification process .

   If you never find the right way , Throw java.lang.AbstractMethodError Abnormal .

IllegalAccessError Introduce

   The program attempts to access or modify a property or call a method , You don't have permission to access , It usually causes compiler exceptions . If this error occurs at execution time , It means that an incompatible change has taken place in a class .

Method call : Virtual method table

   In object-oriented programming , Dynamic dispatch will be used frequently , If we need to search the appropriate target in the method metadata of the class again in the process of each dynamic dispatch, the execution efficiency may be affected . therefore , To improve performance ,JVM Create a virtual method table in the method area of the class (virtual method table)( Non virtual methods don't appear in tables ) To achieve , Use index tables instead of queries .

   Each class has a virtual method table , The table contains the actual entries for each method .

When was the virtual method table created ?

   The virtual method table is created and initialized during the link phase of class loading , After the initial value of the variable of the class is ready ,JVM The method table of this class will also be initialized .

   As shown in the figure , When a method is overridden in a class , So when you call , It will query directly in the virtual method table , Otherwise, it will be connected directly to Object The methods of .

Method return address

   The return address of the method is : Calling the superior method of the method PC The value stored in the register .

   The end of a method , There are two ways :

    1. Normal execution is complete

    2. An unhandled exception occurred , Abnormal exit

   No matter which way to exit , After the method exits, it returns to the location where the method is called . When the method exits normally , Of the caller PC The value of the counter is used as the return address , The address of the next instruction that calls the method . And through the exception exit , The return address is determined by the exception table , Generally, this part of information will not be stored in the stack frame .

When a method starts executing , There are only two ways to exit this method :

  ① The execution engine encountered a bit group code instruction returned by any method (return), A return value is passed to the method caller at the upper level , It is called normal completion export .

    One method is after the normal call is completed , Which return instruction do you need to use , It also depends on the actual data type of the method return value .

   In the bit group code instruction , The return instruction contains ireturn( When the return value is boolean,byte,char,short and int Use ),lreturn(Long Type ),freturn(Float Type ),dreturn(Double Type ),areturn( Reference type ). There's another one return The order is declared void Methods , Example item initialization method , Class and interface initialization methods .

  ② Exception encountered during method execution (Exception), And this exception is not handled within the method , That is, as long as no matching exception handler is found in the exception table of this method , Will cause the method to exit , It is called abnormal completion exit .

    During the execution of the method , Exception handling when throwing an exception , Stored in an exception handling table , It is convenient to find the code to handle the exception when an exception occurs .

   Essentially , Method exit is the process of the current stack frame leaving the stack . Now , Need to restore the regional variable table of the upper method 、 Arithmetic unit stack 、 Push the return value into the operator stack of the caller stack frame 、 Set PC Register value, etc , Let the caller method continue to execute .

   What is the difference between a normal completion exit and an abnormal completion exit : Exit by exception completion exit will not produce any return value to its upper callers .

Some additional information

   Stack frames are also allowed to carry with Java Some additional information about virtual machine implementation . for example : Information that provides support for debugging programs .

Related interview questions

For example, stack overflow ?

  (StackOverflowError)

How to set stack size ?

   Through -Xss Arguments .

Adjust stack size , Can we guarantee that there is no overflow ?

   There is no guarantee that there will be no overflow .

The larger the stack memory allocated, the better ?

   No , The larger the stack memory allocation , In a certain period of time, it has been reduced OOM probability , But it takes up other thread space , Because the whole memory space is limited .

Does garbage collection involve virtual machine stacks ?

   Thread private , Don't involve .

Whether the local variable defined in the method is thread safe ?

   If the object is generated internally , And die inside , No return to the outside , So it's thread safe , On the contrary, the thread is unsafe .

Execution data area , Whether there is Error and GC?

&n

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://cdmana.com/2020/12/20201224152743211k.html

Scroll to Top