Contents of the JVM

0. Java basic test points

Please add a picture description

1. Talk about your understanding of Java

  • Platform independent (compile once, run anywhere)
  • GC (Garbage Cleanup)
  • Language features (generics, reflection)
  • Object-oriented (encapsulation, inheritance, polymorphism)
  • class library
  • exception handling

2. How does Java achieve platform independence (compile in one place and run everywhere)

  • compile time (syntax and semantics are checked)
  • Runtime

javac compiles source code into .class bytecode files.

javap java自带的反编译工具
javac test.java
javap -c test

Please add a picture description

The Java source code is first compiled into bytecode, and then parsed by the JVM of different platforms. The Java language does not need to be recompiled when running on different platforms. When the Java virtual machine executes the bytecode, it converts the bytecode into machine instructions on a specific platform.

Why doesn't the JVM directly parse the source code into machine code for execution?

  • Preparations: Every execution requires various checks. (Syntax and semantic checks are performed at compile time)
  • Compatibility: Other languages ​​can also be parsed into bytecode. (Other languages ​​can also be compiled into .class bytecode files)
  • Platform independence: Platform independence can be achieved. Compile once, execute everywhere.

3. How does the JVM load .class files

Java virtual machine

The JVM shields the difference of the underlying operating system and reduces the complexity of developing based on the native language.

  • memory structure model
  • GC

Please add a picture description

  • Class loader: Load dass files into memory according to a specific format.
  • Execution Engine: Parses commands.
  • Native Interface: The native library that integrates different development languages ​​is used by Java.
  • RuntimeDataArea: JM memory space structure model.

The JVM mainly consists of four parts: Class Loader, RuntimData Area, Execution Engine, and Native Interface. The files that meet the format requirements are mainly loaded into the memory through the Class Loader. And parse the internal bytecode through the Execution Engine, and submit it to the operating system for execution.

4. Talk about reflection

  • The JAVA reflection mechanism is in the running state, for any class, you can know all the properties and methods of this class;
  • For any object, you can call any of its methods and properties;
  • This function of dynamically obtaining information and dynamically calling object methods is called the reflection mechanism of the Java language.

The method to be called:

public class Robot {
    
    

    private String name;

    //    公共的方法
    public void sayHi(String hello) {
    
    
        System.out.println(hello + ":" + name);
    }

    //    私有化的方法
    private String throwHello(String tag) {
    
    
        return "Hello :" + tag;
    }
}

transfer:

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class Test {
    
    
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    
    
        Class robot = Class.forName("com.lydms.IO.Robot");
        Robot r = (Robot) robot.newInstance();
        System.out.println("Class name is" + robot.getName());


//        1、执行private方法throwHello,并接受返回值
        Method throwHello = robot.getDeclaredMethod("throwHello", String.class);
//        将私有化方法设置为可见
        throwHello.setAccessible(true);
//        执行方法,并传入参数,获取返回值
        Object str = throwHello.invoke(r, "Bob");
        System.out.println("Result is " + str);


//        2、执行publi方法sayHi,并指定name的值
        Method sayHi = robot.getMethod("sayHi", String.class);
        sayHi.invoke(r, "Welcome");


//        3、执行publi方法sayHi,并指定name的值
//        获取私有变量的对象
        Field name = robot.getDeclaredField("name");
//        给私有变量设置可见
        name.setAccessible(true);
        name.set(r, "Alice");
        sayHi.invoke(r, "Welcome");
    }
}

The process of class from compilation to execution

  • The compiler compiles the Robot java source file into a Robot.class bytecode file
  • Classloader converts bytecode to Class<Robot> object in JVM
  • The JVM uses the Class<Robot> object to instantiate a Robot object

5. Talk about ClassLoader

Classloader plays a very important role in Java. It mainly works in the loading phase of Class loading, and its main function is to obtain Class binary data stream from outside the system. It is the core component of Java. All Classes are loaded by Classloader. Classloader is responsible for loading the binary data stream in the Class file into the system, and then handing over the Java virtual machine to perform operations such as connection and initialization.

Types of ClassLoaders

  • BootstrapClassLoader: written in C++, loads the core library java.*.
  • Extclassloader: written in Java, loads the extension library Javax.*.
  • AppClassLoader: written in Java, the method of loading the directory where the program is located.
  • Custom Classloader: written in Java, customized loading.

Extclassloader: (extended library Javax.*)

String property = System.getProperty("java.ext.dirs");

AppClassLoader: (the directory where the loader is located)

String property = System.getProperty("java.class.path");

Implementation of custom ClassLoader

key function

Find class files, read binary files

protected Class<?> findClass(String name) throws ClassNotFoundException {
    
    
    throw new ClassNotFoundException(name);
}

Define class (convert byte stream to class)

protected final Class<?> defineClass(byte[] b, int off, int len)throws ClassFormatError{
    
    
    return defineClass(null, b, off, len, null);
}

Load the Class file according to the name/location, call defineClass to parse the byte stream

File to execute:

public class Wali{
    
    
    static{
    
    
         System.out.println("Hello Wali");
        
    }
}

custom class loader

import java.io.*;
public class MyClassLoader extends ClassLoader {
    
    
    private String path;
    private String classLoaderName;


    public MyClassLoader(String path, String classLoaderName) {
    
    
        this.path = path;
        this.classLoaderName = classLoaderName;
    }


//    用于寻找类文件
    @Override
    public Class findClass(String name) {
    
    
        byte[] b = loadClassData(name);
        return defineClass(name, b, 0, b.length);
    }


//    用于加载类文件
    private byte[] loadClassData(String name) {
    
    
        name = path + name + ".class";
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
    
    
            in = new FileInputStream(new File(name));
            out = new ByteArrayOutputStream();
            int i = 0;
            while ((i = in.read()) != -1) {
    
    
                out.write(i);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return out.toByteArray();
    }
}

call class loader

 public class ClassLoaderChecker {
    
    
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    
    
        MyClassLoader m = new MyClassLoader("D:\\", "myClass");
        Class<?> c = m.loadClass("Wali");
//        会调用自定义的findClass( )
        ClassLoader classLoader = c.getClassLoader();
        System.out.println(classLoader);
//        执行加载文件里的方法
        c.newInstance();
    }
}

Parental Delegation Mechanism for Class Loaders

Please add a picture description

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    
    
    synchronized (getClassLoadingLock(name)) {
    
    
        // 1、首先,检查是否已经加载的类
        Class<?> c = findLoadedClass(name);
        if (c == null) {
    
    
            long t0 = System.nanoTime();
            try {
    
    
                if (parent != null) {
    
    
                     2、没有的话,代用父类的加载器
                    c = parent.loadClass(name, false);
                } else {
    
    
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
    
    
                // 如果类没有找到抛出ClassNotFoundException 没有父类加载
            }
            if (c == null) {
    
    
                // 如果仍然没有找到,然后调用findClass去寻找class
                long t1 = System.nanoTime();
                c = findClass(name);
                  这是定义的类装入器;记录数据;
                sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
        }
        if (resolve) {
    
    
            resolveClass(c);
        }
        return c;
    }
}

Why use the parent delegation mechanism to load classes?

  • Avoid bisecting loads of the same bytecode

It is not necessary to save the same class object class. If the delegation mechanism is not used, the Class file is loaded once for each class, and there will be multiple class files in memory. Using the delegation mechanism, the custom classLoader starts to query whether it is loaded layer by layer, and if so, it will no longer be loaded. Make sure there is only one class file in memory.

6. Class loading method

  • Implicit loading: new
  • Display loading: loadClass, forName, etc.

class loading process

Please add a picture description

The difference between loadClass and forName

  • The class obtained by Class.forName has been initialized (loading, linking, initialization)
  • The class obtained by Classloder.loadClass is not yet linked (loading is complete)
package com.lydms.IO;
public class Robot {
    
    
    static {
    
    
        System.out.println("Hello Robot");
    }
}

Load by classLoader (static method not executed)

public static void main(String[] args) throws ClassNotFoundException {
    
    
    ClassLoader classLoader = Robot.class.getClassLoader();
}

Load by Class.forName( ) (execute method in static)

public static void main(String[] args) throws ClassNotFoundException {
    
    
    Class.forName("com.lydms.IO.Robot");
}

7. Java memory model

In the process of program execution, it is necessary to continuously map the logical address of the memory to the physical address, find the relevant instructions and data to execute, and the java runtime faces the same memory limitations as other processes, that is, it is limited by the operating system architecture. The addressable address space provided, the addressable address space provided by the operating system architecture is determined by the number of bits of the operating system, and the 32-bit processor provides an addressable range of 2^32, that is, 4GB.

Kernel space: The kernel is the main operating system program and C runtime space that contains logic and C-based processes for connecting computer hardware, scheduling programs, and providing services such as networking and virtual memory.

User space: User space is the memory space used when the java process actually runs. 32-bit system users can access up to 3GB, and the kernel can access all physical memory, while 64-bit system user processes can access a maximum of more than 512gb, and the kernel code can also access all physical space.

Introduction to memory

Please add a picture description

  • 32-bit processor: 2^32 addressable range
  • 64-bit processor: 2^64 addressable range

Division of address space

  • Kernel space (where the main operating system programs and C run)
  • User space (where the Java program runs)

Please add a picture description

Java Memory Model (Runtime Data Area)

Please add a picture description

JVM memory model—JDK8

Please add a picture description

Program Counter Register

  • An indicator (logical) of the bytecode line number being executed by the current thread.
  • Change the value of the counter to select the next bytecode instruction to be executed.
  • There is a one-to-one relationship with threads, that is, "thread private".
  • Count the Java method, if it is a Native method, the counter value is Undefined
  • No memory leaks will occur.

Java virtual machine stack (Stack)

  • Memory Model of Java Method Execution
  • Contains multiple stack pins

Please add a picture description

Local variable table and operand stack

  • Local variable table: Contains all variables during method execution.
  • Operand stack: stack, pop, copy, exchange, generate consumption variables.
public class ByteCodeSample{
    
    
    public static int add(int a, int b){
    
    
        int c=0;
        c = a + b;
        return c;
    }
}

After javap decompilation

Please add a picture description

execute add(1,2)

Please add a picture description

0:iconst_0: 0 is pushed into the operand stack, 1/2 is put into the local variable table

  • 1: istore_2: Pop the elements in the stack and put them in position 2 of the local variable table.
  • 2: iload_0: Push the 0th element in the local variable onto the stack.
  • 3: iload_1: Push the first element in the local variable onto the stack.
  • 4: iadd: Calculate 0 and 1 in the stack, and push the result to the top of the stack.
  • 5: istore_2: Pop the elements in the stack and put them in the local variable 2 position
  • 6: iload_2: Push the elements in the local variable 2 onto the stack.
  • 7: ireturn: return the elements in the stack

Why does recursion cause java.lang StackOverflow Error exception

When a thread executes a method, a stack needle is created, and the created stack needle is pushed into the virtual machine stack. When the method execution is completed, the stack needle is popped out of the stack. Calling itself all the time, unable to release the stack needle, the recursion is too deep, the number of stack frames exceeds the depth of the virtual stack, and a StackOverflow Error exception is thrown.

The recursion is too deep, and the number of stack frames exceeds the virtual stack depth.

Too many virtual machine stacks will cause java.lang.OutofMemory Error (memory overflow) exception

Stack memory can be automatically released without being reclaimed by GC.

Native Method Stack

Similar to the virtual machine stack, it mainly works on methods marked native

8. The difference between MetaSpace and PermGen

Metaspace: After JDK1.8, the metadata of a class is placed in the local heap memory, which is called MetaSpace. This area belonged to the permanent generation before JDK1.7. Both the metaspace and the permanent generation are used to store class-related information, including the method and field of the class. Both the metaspace and the permanent generation are the realization of the method area, but the implementation method It is different. So the method area is only the specification of the JVM. The JVM constant pool originally located in the method area has been moved to the heap, and the permanent generation has been replaced by the metaspace after jdk8.

,

  • The metaspace uses local memory, while the permanent generation uses JVM memory.
  • This exception does not exist anymore: java.lang.OutOfMemoryError: PermGen space

Advantages of MetaSpace over Permgen

  • The string constant pool exists in the permanent generation, which is prone to performance problems and memory overflow.
  • The information size of classes and methods is difficult to determine, which makes it difficult to specify the size of the permanent generation.
  • PermGen introduces unnecessary complexity to GC.
  • It is convenient to integrate Hotspot with other JVMs such as Jrockit.

Java heap (Heap)

  • The allocated area of ​​the object instance.
  • The main area managed by the GC.

The java heap is a memory area shared by all threads. It is created when the virtual machine starts. The sole purpose of this memory area is to store object instances. All object instances are allocated memory here. It is also the main area managed by GC.

The memory layout of a 32-bit processor java process:

Please add a picture description

Now the collector basically adopts the generational collection algorithm, so the java heap can also be divided into the new generation and the old generation:

Please add a picture description

8. Frequently asked questions about the Java memory model

The meaning of the three major performance tuning parameters of the JVM-Xms-Xmx-Xss

  • -Xms: The initial value of the heap.
  • -Xmx: The maximum value that the heap can reach.
  • -Xss: specifies the size of each thread virtual machine stack (stack)
  • -Xmn10m: Set the new generation size to 20m.

Usually -Xms and -Xmx are written the same to avoid memory jitter and no longer consume performance for expanding memory space;

The difference between the heap and the stack in the Java memory model -> memory allocation strategy

There are three memory allocation strategies when the program is running, static, stack, and heap.

  • Static Storage: The runtime storage space requirements of each data object are determined at compile time. (Static storage means that the storage space requirements of each data object at runtime can be determined at compile time, so that they can be allocated a fixed memory space at compile time. This program allocation strategy requires that there should be no variable data sets in the code. , and nested, recursive structures appear)
  • Stack storage: The data area requirements are unknown at compile time and determined before module entry at runtime. (The program can be dynamically allocated for storage. The program's requirements for the data area are completely unknown at compile time, and can only be known at runtime, but it is stipulated that the size of the memory required by the program must be known when running to the data module to allocate its memory. )
  • Heap storage: The module entry cannot be determined at compile time or runtime, and is allocated dynamically.

Difference between heap and stack in Java memory model

  • Contact: When referring to objects and arrays, the variables defined in the stack save the first address of the target in the heap

Please add a picture description

the difference:

  • Management method: the stack is automatically released, and the heap needs GC.
  • Space size: the stack is smaller than the heap.
  • Fragmentation related: The fragmentation generated by the stack is much smaller than that of the heap.
  • Allocation method: the stack supports static and dynamic allocation, while the heap only supports dynamic allocation.
  • Efficiency: The stack is more efficient than the heap.

The relationship between metaspace, heap, and thread-exclusive parts—memory perspective

public class HelloWorld {
    
    
    private String name;


    public void getName() {
    
    
        System.out.println("Hello" + name);
    }


    public void setName(String name) {
    
    
        this.name = name;
    }


    public static void main(String[] args) {
    
    
        int a = 1;
        HelloWorld hw = new HelloWorld();
        hw.setName("Test");
        hw.getName();
    }
}

Please add a picture description

Differences in the intern( ) method between different versions—JDK6 VS JDK6+

String s = new String( "a")
s .intern( );
  • JDK6: When calling the intern method, if the string constant pool has previously created the string object, return the reference to the string in the pool. Otherwise, add this string object to the string constant pool, and return the reference of this string object.
  • JDK6+: When calling the intern method, if the string constant pool has previously created the string object, then return the reference to the string in the pool. Otherwise, if the string object already exists in the Java heap, add a reference to this object in the heap to the string constant pool and return the reference; if it does not exist in the heap, create the string in the pool and return its reference.

Please add a picture description

10. String constant pool

The constant pool in the JVM is moved from the permanent generation to the heap.

public class PermGenErrTest {
    
    
   public static void main(String[] args) {
    
    
       for (int i = 0; i < 1000; i++) {
    
    
//            将返回的随机字符串添加到字符串常量池中
           getRandomString(100000).intern();
       }
       System.out.println("Creat End");
   }


   //    返回指定长度的随机字符串
   private static String getRandomString(int length) {
    
    
//        字符串源
       String str = "asdfasdfiouwerwelsdfkjsafjiasfnsnfsdafsfs";
       Random random = new Random();
       StringBuffer sb = new StringBuffer();
       for (int i = 0; i < length; i++) {
    
    
           int number = random.nextInt(20);
           sb.append(str.charAt(number));
       }
       return sb.toString();
   }
}

Set the permanent generation size

-XX: MaxPermSize=6M    永久代最大为6M
-XX: PermSize=6M        初始时永久代大小
-XX:MaxDirectMemorySize 可以设置java堆外内存的峰值

JDK6 (report exception - permanent generation memory overflow)

Please add a picture description

JDK7+ (normal execution)

Please add a picture description

public class Test {
    
    
    public static void main(String[] args) {
    
    
//        存在堆中
        String s = new String("a");
//        想放到常量池中,但是其中已经存在,放失败
        s.intern();
//        常量池中
        String s2="a";
        System.out.println("s==s2: "+(s==s2));

//        拼接为"aa",在进行比较
        String s3 = new String("a") + new String("a");
        s3.intern();
        String s4="aa";
        System.out.println("s3==s4: "+(s3==s4));
    }
}

Output result:
In JDK6:

s==s2: false
s3==s4: false

In JDK6+:

s==s2: false
s3==s4: true

Parse:

It is to create "a" in the constant pool, and then create the space for "a" in the heap. That is to say, it takes up 2 memory spaces.

String s = new String("a");

Create "aa" in the heap and place "aa" in the constant pool

String s3 = new String("a") + new String("a");
s3.intern();

s==s2: false

String s = new String("a");在堆中创建内存空间,s指的是堆内存地址。
String s2="a";引用的是常量池中的地址。

s3==s4: true

JDK6:中副本,指向的是常量池和堆中
JDK6+:常量池中可以放置引用。
生成的s3值"aa",存在于堆中,将其引用放在常量池中。
s4创建的时候,查看常量池中有"aa"的引用(指向堆中),则使用该引用。则S3==S4(true
堆中"aa",常量池中有"aa"的引用。

Guess you like

Origin blog.csdn.net/weixin_44624117/article/details/131318405
JVM
JVM