JVM

Tue, Jan 18, 2022 7-minute read

JVM note

JVM memory

ClassLoader

image

ClassLoader

ClassLoader parent first

Classes loaded with parent class loader first is the default value for class loading mode. This value is also known as parent first

image

ClassLoader

Java Virtual Machine Stack

exceptions in real life 开发中遇到的异常有哪些

image

exceptions

  • StackOverflowError
  • OutOfMemoryError、

method

non virtual method in java

non-virtual methods in Java are private, final, static, constructor, non-virtual methods do not need to traverse the method table of the method area according to the specific object, to determine the calling relationship

Invoking a java method

non-virtual

  • invokestatic
  • invokespecial:
    • invocation of instance initialization () methods
    • invocation of private methods
    • invocation of methods using the super keyword

virtual(exception final)

  • invokevirtual
  • invokeinterface
  • invokedynamic

Q1: StackOverflowError

StackOverflowError is an error which Java doesn’t allow to catch, for instance, stack running out of space, as it’s one of the most common runtime errors one can encounter.

The main cause of the StackOverflowError is that we haven’t provided the proper terminating condition to our recursive function or template, which means it will turn into an infinite loop

For example: Lack of proper or no termination condition. This is mostly the cause of this situation termed as unterminated or infinite recursion.

/ Java program to demonstrate
// infinite recursion error
  
public class StackOverflowErrorClass {
    static int i = 0;
  
    // Method to print numbers
    public static int printNumber(int x)
    {
  
        i = i + 2;
        System.out.println(i);
        return i + printNumber(i + 2);
    }
  
    public static void main(String[] args)
    {
        // Recursive call without any
        // terminating condition
        StackOverflowErrorClass.printNumber(i);
    }
}

-Xss set up stack’s size OOM

Q2: Does garbage collector work on stack

No, Garbage Collector In Java works only on Heap memory and not on stack memory , because of the main principal that stack works on which is

Q3: Does Local variables are thread safe within a method

Local variables are thread safe within a method as long as you don’t pass them to other thread. If you do, then it depends. For example, in your code all the threads you create have shared access to outputWindow and threads.

  • s1: 如果只有一个线程才可以操作此数据,则必是线程安全
  • s2:多个线程操作此数据,则此数据是共享数据。如果不考虑同步机制的话,会存在线程安全问题
public class StringBuilderTest {

    // s1:安全
    public static void method1() {
        StringBuilder sb = new StringBuilder();
        sb.append("a");
        sb.append("b");
    }

     // s2:不安全
    public static void method2(StringBuilder sb) {       
        sb.append("a");
        sb.append("b");
    }

    // s1:有可能是线程不安全的, 返回s1有可能被其他线程使用
    public static StringBuilder method3() {
        StringBuilder sb = new StringBuilder();
        sb.append("a");
        sb.append("b");
        return s1;
    }

    // s1:线程安全
    public static String method4() {
        StringBuilder sb = new StringBuilder();
        sb.append("a");
        sb.append("b");
        return sb.toString(); // create a copy,
    }
}

堆区大小- 选项 “-Xmx” 和 “-Xms” 设置

  • -Xms 等于 -XX:InitialHeapSize
  • -Xmx 等于 -XX:MaxHeapSize
  • 通常这两个参数配置相同,目的是为了能够在 java 垃圾回收机制清理完堆区后不需要重新分割计算堆区的大小,从而提高性能

-XX:NewRation=2,新生代 1, 老年代 2, 新生代占整个堆的 1/3

逃逸分析之: 栈上分配:堆分配转化为栈分配

逃逸分析之: 代码优化之同步省略(消除)

  • 线程同步的代码是相当高的,同步的后果是降低并发性和性能

  • JIT 编译器可以借助逃逸分析来判断同步块所使用的锁对象是否只能够被一个线程访问而没有被发布到起到线程, 那么 JIT 编译器在编译这个同步块的时候就会取消对部分代码的同步, 这样就能大大提高并发性和性能。这个取消同步的过程叫锁消除

public void f() {
    Object hollis = new Object();
    synchronized(hollis) {
        System.out.println(hollis);
    }
}
public void f() {
    Object hollis = new Object();
    System.out.println(hollis);
    
}

逃逸分析之: 分离对象或标量替换: 有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分或者全部可以存储在 CPU 寄存器中

Thread and runtime dataAreas

image

Thread runtime dataAreas

Q1: jvm memory model, how many types of memory areas are allocated by JVM

Q2: Jave 8 memory model improve, how many types of memory areas are allocated by JVM

image

Jave 8 memory model

image

Jave 8 memory model

Q3: jvm memory model, difference between stack and heap, heap structure, why there are two survivor space

Q4: why there is YC and OC space in JVM

Q5: talk about the database when running the jvm

Q6: when the object enter the Tenure generation space

Q7: Eden and Survior ratio, why there is YC, OC, persistence space, why YC divided into Eden and Survivor

Q8: the memoro allocation in JVM, does the GC happen in persistence? why YC, OC

Q2: 对象头信息里面又什么东西 Q3: java 对象头里有什么


Objectify

create object methods in java

  • new
  • Class newInstance()
  • constructor newInstance()
  • clone()
  • deserialization
  • factory method

steps of creating object in java

image

creating object JVM

  1. findout Symbol reference in constant pool, whether it goes through loadlink ( verification 、 Get ready 、 analysis )initialization.

If (not), in parent delegation mode, use the current class loader to find the corresponding .class file with ClassLoader + package name + class name Key to complete the loading of the class into memory. In this process, if the JVM cannot find the class to be loaded, it will throw a ClassNotFoundException exception, which means that the class cannot be found to load.

  1. a stack memory allocation
  • Bump the Pointer:Bump allocation is a fast, but limited approach to allocation.(memory is compacted)

  • FreeList : It operates by connecting unallocated regions of memory together in a linked list, using the first word of each unallocated region as a pointer to the next. It is most suitable for allocating from a memory pool, where all objects have the same size. (memory is not compacted)

  1. solves concurrency problems
  • CAS(Compare-and-Swap)
  • TLAB : a single thread can allocate new objects in this area (Eden)
  1. initialize memory to zero

  2. create Java object header

  3. JVM calls a special method named

memory layout in Java objectct

  1. Object head

    • 1.1 Mark Word

      • 1.1.1 hashcode
      • 1.1.2 GC generation age
      • 1.1.3 lock information
      • 1.1.4 biased thread ID
      • 1.1.5 biased timestamp
      • 1.1.6 object generation age
    • 1.2 Klass Pointer

      • Type pointer, through which an object can know which class the object is an instance
    • 1.3 Array Length

      • Record the length of the array
  2. Instance data

    • the various attribute values set by the programmer
  3. Padding

    • instance part is not an integer multiple, it is necessary to add a bit of placeholder to meet the requirements

Q1: how object stored in JVM

Q2: 对象头信息里面又什么东西? Q3: java 对象头里有什么


Q1: intern()

  • 常量与常量的拼接结果在常量池,原理是编译器优化

  • 常量池中不会存在相同内容的常量

  • 只要其中有一个是变量,结果就是堆中。变量拼接原理是 StringBuilder Instance variables are created in the heap

  • 如果拼接结果调用 intern() 方法,则主动将常量池中还没有的字符串对象放入池中,并返回此对象地址 We know that string literals are created in the String pool, and string objects are created in the heap memory area. We can use the method String.intern() to create string literals for the string objects. When invoked on a string object, method intern() creates an exact copy of a String object in the heap memory and stores it in the String constant pool.

  • (“a” + “b” + “c” ).intern() == “abc”

string concatenation operator ( + ) vs append

public void test() {
    long start = System.currentTimeMillis();
    method1(10000);
    //method2(10000);
   long end = System.currentTimeMillis();
   System.out.println(end - start);
}

public void method1(int highLevel) {
    String src = "";
    for (int i = 0; i < highLevel; i++) {
        src = src + "a"; // every time create a stringbuilder, string
    }
}
//4014
public void method2(int highLevel) {
    StringBuilder src = new StringBuilder();
    for (int i = 0; i < highLevel; i++) {
        src.append("a"); 
    }
}
// 7
  • StringBuilder 的 append()效率要原高于拼贴
    • StringBuilder 的 append()只创造了一个 SB
    • 拼贴创造了多个 sb 和 String 的对象
    • 拼贴占据了更多的内存

StringBuilder 改进空间

底层是 16 的容量: 在实际开发中,如果基本确定要前前后后添加的字符串长度不高于某个限定值 highLevel,建议使用构造器 StringBuilder s = new StringBuilder(highLevel)

public AbstractStringBuilder append(String str) {
    if (str == null) 
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}  

public void ensureCapacityInternal(int minimumCapacity) {
    if ( minimumCapacity - value.length > 0) {
        value = Arrays.copyOf(value, 
                newCapacity(minimumCapacity));
    }
}  

Q1 new String(“ab”) 会创建几个对象

2 个: 堆空间 new 一个 Stringbuilder, 在常量池放入 ”ab“ 如何证明: 字节码 ldc

Q2 new String(“a”) + new String(“b”) 会创建几个对象

  • Obj 1. new Stringbuidler()
  • Obj 2. new String(a)
  • Obj 3. 常量池中 “a” // obj2 new String(a)
  • Obj 4. new String(b)
  • Obj 5. 常量池中 “b”

深入:Stringbuidler toString()

  • Obj 6. new String(“ab”) // 此时字符串常量池中不存在 ”ab“

Q3: intern()

image

intern()

image

intern()

image

intern()

image

intern()

Q4: intern()

image

intern()

image

intern()

image

intern()


JVM2