Technology Sharing

Interview Question 005-Java-JVM (Part 1)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Interview Question 005-Java-JVM (Part 1)

Self-test

  • 1. What are the components of JVM?
  • 2. What areas are included in the runtime data area?
  • 3. What data is stored in the stack and heap respectively?
  • 4. Why should PermGen be replaced by MetaSpace?
  • 5. Do you understand the basic structure of the heap space? Under what circumstances will an object enter the old generation?
  • 6. In which memory area are large objects placed?
  • 7. How to create a Java object?

Question Answer

1. What are the components of JVM?

Answer: JVM is a program that can executeBytecode(.class) files, and also provides mechanisms such as memory management and garbage collection. It consists of the following main parts.

  • Class loading subsystem: responsible for loading bytecode files (.class) into the JVM.
  • Runtime data area: It is the memory area used by the JVM during execution.
  • Execution engine: responsible for interpreting or compiling bytecode into machine code for execution by the processor.
  • Native library interface: provides a set of APIs for calling the operating system or native libraries written in other languages.

2. What areas are included in the runtime data area?

Answer: The runtime data area is the memory area allocated by the JVM when executing a Java program.

  • Program counter: It is a small memory space, which is the address of the bytecode instruction currently executed by the current thread. If the thread is executing a native method, the value of this counter is undefined.
  • Java virtual machine stack: Each thread will create a virtual machine stack when it is created, which is used to store the thread's local variable table, operand frame, dynamic link, method exit information, etc. The Java virtual machine stack contains multiple stack frames. The process from the call to the completion of each method corresponds to the process of pushing and popping a stack frame in the virtual machine.
  • Native method stack: It is the space prepared by JVM to run Native methods. It has similar functions to the Java virtual machine stack. It is a memory model that describes the running process of native methods.
  • Heap: Used to store almost all object instances and arrays, and is the main working area of ​​the garbage collector.
  • Method area: used to store class information, constants, static variables, and code compiled by the just-in-time compiler loaded by the JVM. Before JDK1.8, it was implemented as a permanent generation. Starting from JDK1.8, the permanent generation was replaced by the original space. Metaspace uses local memory instead of heap memory.
    Java virtual machine runtime data area

3. What data is stored in the stack and heap respectively?

Answer: Data stored in the stack (Java virtual machine stack):

  • Local variable table: mainly used to store method parameters, local variables within the method, data types include basic data types and object references.
  • Operand stack: used to temporarily store operation instructions and intermediate results during method execution.
  • Dynamic linking: A reference to the constant pool of the class to which the method belongs, used to resolve symbolic references in the method.
  • Method return address: stores the address of the next instruction executed after a method call.
    Data stored in the heap:
  • Object instance: An object instance created in a program using the new keyword, including the object's properties and methods.
  • Arrays: Arrays of all types, including primitive type arrays and object arrays.

4. Why should PermGen be replaced by MetaSpace?

Answer: Replacing the permanent generation with metaspace is mainly to solve some inherent problems and limitations of the permanent generation and improve the performance and flexibility of the JVM.

  • Improve the flexibility and efficiency of memory management: The memory size of the permanent generation is set when the JVM is started and cannot be adjusted dynamically. Metaspace uses local memory instead of Java heap memory, and its size can be adjusted dynamically as needed.
  • Solve class unloading and garbage collection problems: The GC behavior of the permanent generation is more complex and unpredictable, and the recovery efficiency is low.
  • Provide better performance and stability: Using Metaspace makes JVM memory management more unified and consistent, because Metaspace, like other memory areas, is managed using local memory. This can simplify memory management strategies and improve overall performance and stability.
  • Simplify JVM memory management

5. Do you understand the basic structure of the heap space? Under what circumstances will an object enter the old generation?

A: The basic structure of the heap space is mainly composed of the new generation, the old generation, and the permanent generation. After JDK8, the permanent generation is replaced by the metaspace, which uses local memory for storage.

  • New Generation: The new generation is further divided into the Eden area and two survivor areas (Survivor 0 and Surivivor 1)
    • Eden area: Newly created objects are first allocated memory in the Eden area.
    • Survivor space (S0, S1): used to store objects that survive the new generation garbage collection. After each Minor GC, the surviving objects are copied back and forth between these two spaces.
  • Old generation: Objects that survive multiple Minor GCs. The frequency of garbage collection (Major GC or Full GC) in the old generation is low.
  • Permanent generation/metaspace: used to store class metadata, including class definitions, constants, static variables, just-in-time compiled code, etc.

The situation of objects in the old age:

  • Age threshold reached: Each object has an age when memory is allocated in the new generation, and the age increases by 1 after each Minor GC. When the age reaches a certain threshold (the default is 15), the object will be promoted to the old generation.
  • Large objects: If the object is too large and exceeds the threshold set by the JVM, the object will be allocated space directly in the old generation.
  • Insufficient space in the Survivor space: If the survivor space does not have enough space to accommodate all surviving objects during Minor GC, these objects will be
  • Dynamic object age determination: If the size of all objects of the same age in the Survivor space exceeds half of the Survivor space, objects older than or equal to that age can directly enter the old generation.
// 动态年龄计算代码
uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
 //survivor_capacity是survivor空间的大小
size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);//TargetSurvivorRatio 为50
size_t total = 0;
uint age = 1;
while (age < table_size) {
total += sizes[age];//sizes数组是每个年龄段对象大小
if (total > desired_survivor_size) break;
age++;
}
uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
  ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

6. In which memory area are large objects placed?

A: Large objects (very large arrays and strings) are usually allocated directly in the old generation memory area. This is to avoid frequent allocations in the new generation.Garbage CollectionWhen large objects are frequently copied between the Eden area and the Survivor area, the garbage collection efficiency is improved.
Configure the threshold for large objects to enter the old generation directly:

# 将大于1MB的对象直接分配在老年代
java -XX:PretenureSizeThreshold=1m -jar your-application.jar
  • 1
  • 2

7. How to create a Java object?

answer:

  1. Class loading check
    • If the class has not been loaded, linked and initialized, the JVM will first load the class. This includes the following steps:
      • Loading: The class file is read through the class loader and the bytecode of the class is loaded into the memory.
      • Connection: includes three stages: verification, preparation, and parsing. Verify the correctness of the class file, prepare the static variables of the class and allocate memory, and resolve symbol references to direct references.
      • Initialization: Execute the static initialization block of the class and the initialization of static variables.
  2. Memory allocation
    • JVM allocates memory for new objects in the heap. The size of the allocated memory is determined by the structure of the object, including the object header and instance data.
    • The JVM has two main ways of allocating memory:
      • Bump-the-pointer: If the heap memory is neat, the allocation pointer only needs to move a specified amount of memory to the free memory area.
      • Free List: If the heap memory is irregular, the JVM needs to maintain a free list and find the appropriate block from the free list when allocating memory.
  3. Initialize to zero value
    • The JVM will initialize all instance variables of the object to default values. For example, numeric type variables will be initialized to 0, Boolean type variables will be initialized to false, and reference type variables will be initialized to null.
  4. Set the object header
    • Set the object header information in the object's memory space, which includes the object's hash code, GC generation age, lock status flag, locks held by the thread, biased thread ID, etc.
  5. Constructor initialization
    • Call the object's constructor to complete the object's initialization. This includes executing explicit initialization operations on instance variables and the code in the constructor body. The specific steps are as follows:
      • Executes the instance initialization block of the class.
      • Execute the parent class's constructor from top to bottom according to the inheritance hierarchy.
      • Initializes instance variables to explicitly specified values.
      • Execute the main part of the class's constructor.
/**
 * 创建对象的示例代码
 */
public class MyClass {
    private int value;

    public MyClass(int value) {
        this.value = value;
    }

    public static void main(String[] args) {
        MyClass obj = new MyClass(10);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • The execution process of the above code example is as follows:
    • Class loading: JVM checks if MyClass is already loaded. If not, it loads the MyClass class.
    • Memory allocation: Allocate memory in the heap for the new instance of MyClass.
    • Memory initialization: Initialize the allocated memory to default values.
    • Set object header: Set metadata in the object header.
    • Constructor initialization: Execute the constructor of MyClass and initialize the instance variable value to 10.

References