Java Virtual Machine JVM

This article focuses on where memory is used when the JVM is running

The heap

Java allocates memory in the heap for all objects. The size of the heap can be dynamically expanded. The -xms and -xmx virtual machine parameters can be used to specify the heap size of a program, with the first parameter setting the initial value and the second parameter setting the maximum value.

Note that the class information is stored in the method area, but the class object created from the class information is in the heap

The garbage collection mechanism gc is primarily for the heap

The stack

The stack area belongs to the thread unique, different threads have different stack area, the stack area mainly includes the program counter, virtual machine stack, local method stack three parts

Program counter

Record the instruction address of the virtual machine bytecode executed by the current thread (i.e. which line the code was executed on)

The virtual machine stack

The -xss virtual machine parameter can be used to specify the memory occupied by each thread. The memory used by the stack is off-heap memory, and each time a thread is created, it needs to request memory from the operating system

The virtual machine stack stores stack frames, and each time a method is executed, a stack frame is added. The process from method invocation to completion corresponds to the process of a stack frame being pushed and removed from the Java virtual machine stack.

Here the stack is the stack structure, advanced and then out, the recursion of the method corresponds to the characteristics of the stack advanced and then out, the execution of method A, A to the stack, A to call method B, B to the stack, B to the stack, and then the execution of A, A to the stack.

The stack frame

The stack frame contains all the elements needed for a method to execute, and stores information such as local variable tables, operand stacks, constant pool references, and so on

Local method stack

The local method stack is similar in structure and function to the Java virtual machine stack, except that the local method stack serves the local method.

Native methods, which are typically written in other languages (C, C++, assembly language, etc.) and compiled into programs based on native hardware and operating systems, require special treatment.

Method area (known as persistent generation before JDK 1.8)

(1) JdK1.8 is a separate memory area, connected to the memory area of heap memory, used to store loaded class information, constants, static variables, just-in-time compiler compiled code, etc.

(2) Use -xx :MaxPermSize to set the maximum space that can be allocated for the permanent generation. If the JVM loads more class information than this value, an OOM:PermGen error will be reported

(3) The permanent generation’s GC is tied to the old generation’s GC, so whoever fills up will trigger the permanent generation and the old generation’s GC.

(4) After JDK1.8, the data of the original permanent generation is divided into heap and meta space. The meta space stores the meta information of the class (i.e. symbolic references in the class constant pool), static variables and constant pools, and so on in the heap.

Effects of reflection on the method area

Method for the structure of the area after the main storage class loading information, because the JVM for class loading is not a one-time full load of the structure, and reflected in the use of class if there is no load, will trigger a class load, equivalent to make more information class methods zone, may lead to memory overflow (although also is loading the classes in the project, But it’s loading at the wrong time.)

The impact of dynamic proxies on the method area

(1) Dynamic proxies make extensive use of reflection, so the impact is consistent with reflection.

(2) Dynamic proxies create new class structures. Load more class information

Various constant pools

constant

Constants with final modified member variables cannot be changed once given!

Final modifies three types of variables: static variables, instance variables, and local variables (defined ina method), representing three types of constants.

Class Constant pool (static constant pool)

The class constant pool is the part of a Java file that has been compiled into a class file.

Java files are compiled into class files. In addition to the class version, the class file contains the Constant Pool, which is used to store various Literal and Symbolic References generated by the compiler.

Literals are: text strings, constant values, base attribute type values, etc.

Symbolic references: class structure, attribute type and name, method name and related information

Run-time constant pools (commonly referred to as constant pools)

When a class is loaded into memory, the JVM stores the contents of the class constant pool into the runtime constant pool, which contains information about each class.

After JDK 1.8, symbolic references from the class constant pool are stored in meta space, and literals are stored in heap space

String constant pool

String constant pool can be thought of as belonging to the runtime constant pool, it is the content of the class loading is completed, after verification, in the heap after preparation phase generated string object instance, then the string object instance reference value to a string constant pool. (or string constant pool is in the class after the completion of the loading fill.)

You can manually add String constants using the string.intern () method

Integer constant pool, floating point constant pool

Constants cannot be added manually to a constant pool created by the JVM.

dimension

The part of the symbol reference stored in the class constant pool.

In Java8, Metaspace takes the stage, and method areas live in Metaspace. At the same time, the meta space is no longer contiguous to the heap, but is in Native memory.

Local memory

Native memory, also known as C-heap, is used by the JVM’s own processes. Native memory is not part of the Heap, but it is accessible to the JVM. GC is triggered when the Java Heap space is low, but not when the Native Memory space is low.

Why does a metacolith replace a permanent generation

This is mainly to avoid OOM exceptions. Because it is common to use PermSize and MaxPermSize to set the size of the permanent generation to determine the upper limit of the permanent generation, it is not always possible to know how appropriate it should be, and it is easy to get OOM errors if you use the default.

When using meta-space, the number of classes of metadata that can be loaded is no longer controlled by MaxPermSize, but by the actual available space on the system.

When GC occurs in a meta-space

If the metaspacesize parameter is set to the metspace, the collection of information about classloaders and useless classes is triggered when this value is reached.

Object creation process

New an object

(1) First check whether the class has been loaded. If so, create an instance directly from the class object in the heap. If not, the class is loaded, the class information is loaded into the method area, and a globally unique class object is generated in the heap. All instances are created from class objects (using class object constructors)

(2) Allocate memory space in the heap (by pointer collision or space list)

If memory in the Java heap is perfectly neat, all used memory is placed on one side, free memory is placed on the other, and a pointer is placed in the middle as a pointer to the dividing point. The allocated memory simply moves that pointer to the free space by an equal distance to the size of the object. This allocation is called a “Bump thePointer.”

If memory in the Java heap is not neat, used memory and free memory cross each other, that is simply no way pointer collision, the virtual machine, you must maintain a list of records on which memory blocks are available, at the time of distribution from the list to find a large enough space division to the object instance, and update the list of records, This type of allocation is called a “FreeList.”

(3) Set the object header, such as the object is an instance of the class (that is, the class), how to find the metadata information of the class, the hash code of the object, the age of the GC generation of the object and other information, these information is stored in the object header.

(4) Object property initialization, call init() method, that is, according to the constructor initialization

(5) Point a reference to the object

Class loading process

Java hot update | 7 clock

Class loader

The Java class loader this | 7 clock

Four reference types

Java four reference types most detailed explanation

Garbage collection mechanism

The life cycle of the stack is the same as that of the thread, so the stack space does not need to be reclaimed, and the heap memory, which is the main consumer of memory, needs a mechanism to reclaim unused memory. The JVM implements the garbage collection mechanism of the heap instead of the programmer, so the programmer does not have to actively worry about this part.

How do I find useless objects?

JVM with reference counting:

When an object is created, it is assigned a reference counter (which can be placed in the object’s header). A reference count of 0 indicates that the object is useless.

If two objects refer to each other, they will never be reclaimed, causing a memory leak.

JVM using reachability analysis:

According to the accessibility analysis method, it is meaningful to start from all GC roots, search for references layer by layer, and then reach the objects, other objects can be recycled.

GC Roots

Which objects can be considered GC Roots, and the JVM looks for them as a starting point for the graph.

  • (1) Objects referenced in the virtual machine stack (local variable table, i.e. objects being used by threads
  • (2) The object referenced by the static attribute in the method area, namely the static variable of the class
  • (3) Objects referenced by constants in the method area (in the runtime constant pool)
  • (4) Objects referenced in the local method stack (Native objects)

Garbage collection algorithm

Different JVM VMS choose different garbage collection algorithms

Mark-recycle

Mark phase: Mark objects that need to be reclaimed.

Cleanup phase: Reclaim the internal space of the marked recyclable object. b

Disadvantages:

  • (1) The algorithm needs to suspend the whole application, which is not efficient.
  • (2) A large number of discontinuous memory fragments will be generated after the mark is cleared. Too many fragments may lead to the failure to find enough space for large objects in the subsequent process and trigger a new garbage collection action in advance.

Replication algorithm

The replication algorithm divides the available memory into two pieces, uses only one piece at a time, and when this piece of memory is used up, copies the remaining objects onto the other piece, and then cleans up the used memory all at once.

Cons: Half as much memory; The efficiency of the algorithm is related to the number of viable objects, the more viable objects, the lower the efficiency.

Mark-tidy

A combination of mark-reclaim and copy algorithms that move surviving objects to one side and then delete the other

Generational collection algorithm

The generational collection algorithm is currently used by most JVM garbage collectors.

The core idea is to divide memory into several different regions based on the life cycle of the object. The reactor is normally divided into Tenured Generation and Young Generation.

How does the object record age

This means that each object has an age. If the JVM uses a generational collection algorithm, it adds an age to the avatar when creating an object instance

How does the object age

The age of this object instance is +1 each time it undergoes GC.

What is the function of generations?

The characteristics of the old generation are that only a small number of objects need to be recycled in each garbage collection, while the characteristics of the new generation are that a large number of objects need to be recycled in each garbage collection. Therefore, the most suitable collection algorithm can be adopted according to the characteristics of different generations.

Young generation (using mark clear + copy algorithm)

Tag clearing algorithm: it is used for GC of the whole generation, so there will be memory fragmentation

Replication algorithm: it is reflected in the Eden area, survivor area and replication movement of the old age, which fully eliminates memory fragmentation.

  • The new generation memory is divided into one Eden zone and two survivor zones (survivor0,survivor1) in a 8:1:1 ratio.
  • Eight: one: one
  • eden : survivor0 : survivor1

(1) All newly generated objects are in Eden area.

(2) After each GC: the surviving object in Eden is moved to survivor0 and Eden is emptied. This way Eden is always empty after GC and new objects are put in without memory fragmentation

(3) After a GC, if Eden is put into survivor0, and it is found that Eden cannot be put into Survivor0, Eden and all survivable objects of survivor0 will be moved to Survivor1 ().

When survivor1 can be lowered: (although survivor0 and survivor1 have the same memory size)

In survivor0, objects are reclaimed every time a GC is performed, so there is memory fragmentation, and it is possible to put the two pieces into survivor1 when they are moved. Then empty Eden and survivor0 and put survivor1 back to Survivor0 (equivalent to a memory fragmentation removal).

When survivor1 cannot be laid down: move directly to old age.

The young GC triggers MinorGC

A young GENERATION GC will be triggered when Eden is overloaded

Old age (using mark-clean or mark-clean algorithms)

There are three ways to enter the old age:

(1) Old enough:

When the age of the object reaches a certain threshold, the object will enter the old generation. The age threshold for the object to be promoted to the old age can be set by using -xx :MaxTenuringThreshold.

(2) Sufficiently large situation:

If it is a large object (a long array of strings) it can go straight to the old age. Virtual machine provides a – XX: PretenureSizeThreadhold parameters, make greater than this parameter value distribution of objects directly in the old age

(3) Young generation Survivor1 is full

– All surviving objects in Eden and Survivor1 of the young generation will be moved to the old age at once

Full GC is triggered in the old generation

Trigger a Full GC when the old age is Full

reflection

Essentially, Java allows you to get all the information about a class object by getting its properties. So make sure you get its class object.

Reflection refers to:

  • (1) In the JVM running state, for any class can get its properties, methods, constructors
  • (2) In the JVM running state, for any instance can call its properties and methods

This is important because each real example holds a reference to a class object, so you can get the class object by instance.

How do I get a class object

(1) Get the class object from the instance

The base Object class has a getClass method to get the class Object of the instance

(2) Any data type (including basic data types) has a “static” class attribute

For example, Class aa = integer. Class and Class bb = string. Calss are directly Class objects. It’s hard coded

Class. ForName (String name);

You can get the class object directly from the package name + the class name. It is often possible to scan all classes under a package to get all class names

Why pass in a target object when reflection calls a method?

When invoking a method (obj, args), invoke an obJ object, which is the object you expect to execute the method on. It can also be an object you create.

A dynamic proxy

The purpose of dynamic proxies is to create new classes without having to code the target classes in advance.

Static agent

You can only proxy methods of the interface implemented by the target class, not private methods.

Premise: The target class implements an interface

  • (1) Create a proxy class to implement this interface
  • (2) Add a constructor to the proxy class that takes the target class
  • (3) write the expected proxy method of the proxy class, which can use the reference of the target class to control the execution of the target class method
  • (4) Use target classes to build proxy classes where they should be used, and then create instances to use them

JDK dynamic proxy

The target class must implement an interface and delegate methods in the interface.

(1) Use the getProxyClass(ClassLoader, interfaces) method of the ProxyClass, which returns the ProxyClass object as long as you pass it a ClassLoader and a set of interfaces. The proxy class object has all the methods and argument lists in the interface. This is done by reflection.

(2) Using the proxy class object, create a Constructor with arguments and get a Constructor instance. Parameters for InvocationHandler. Class

(3) Create an instance of InvocationHandler.class and implement the invoke() method, which can be used to delegate enhancements to all or specified methods. Note that in the invoke() method, reflection is required to execute the method of the original object, so the original object must also be passed in.

(4) Then use constructive.newinstance (invocationHandler) method to get the instance of the proxy object.

To create a JDK dynamic proxy, you need three things: 1. Interface class 3. InvocationHandler class

public class ProxyTest { public static void main(String[] args) throws Throwable { CalculatorImpl target = new CalculatorImpl(); 1. Generate proxy object 2 based on the interface it implements. The proxy object calls the target object method Calculator calculatorProxy = (Calculator) getProxy(target); calculatorProxy.add(1, 2); calculatorProxy.subtract(2, 1); } private static Object getProxy(final Object target) throws Exception {// Parameter 1: find a class loader for it, parameter 2: The interface implemented by the target object, Class proxyClazz = proxy.getProxyClass (target.getClass().getClassLoader(), target.getClass().getInterfaces()); Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class); Object proxy = constructor.newInstance(new InvocationHandler() { @Override public Object invoke(Object proxy, Method Method, Object[] args) throws Throwable {system.out.println (method.getName() + "Method starts executing..." ); Object result = method.invoke(target, args); System.out.println(result); System.out.println(method.getName() + "End of method..." ); return result; }}); return proxy; }}Copy the code

Is the dynamic proxy class a brand new class

Yes, the dynamic proxy class has an InvocationHandler property that implements the proxy functionality compared to the propped class. So it’s a whole new class structure.

Why use the interface to generate the proxy class object instead of the target class object itself?

(1) Because if an interface is used to generate, the class object created by the same set of interfaces does not need to be created again when the getProxyClass() method is called because of the cache. Therefore, although the target class needs to be passed in every instance of the dynamic proxy, when the proxy class is constructed, Instead of creating a proxy class object, you create a new instance of the proxy class object.

(2) The interface is also convenient for judging whether an instance needs to be used by proxy.

CgLib dynamic proxy

This approach to dynamic proxy does not require a proxy class to implement an interface, but rather creates a subclass of the proxy class

  • (1) Create a subclass of the proxy class so that it can call the original method of the parent class
  • (2) Use ASM technology to weave enhanced methods for subclasses and generate binary bytecode of proxy classes.
  • (3) Load binary bytecode and generate Class object
  • (4) Use the class object to get the constructor, and then create an instance of the proxy class to return

Enhancement method written:

public class MyMethodInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println("Before:" + method); Object object = proxy.invokeSuper(obj, arg); System.out.println("After:" + method); return object; }}Copy the code

Intercept method parameters are 1, proxy object; 2. Delegate class method; 3. Method parameters; 4. The MethodProxy object for proxy methods.

To create a proxy object:

Enhancer enhancer = new Enhancer(); // Inherits the target class, henhancer.setSuperclass (userServiceImp.class); // Weave into enhancer.setCallback(new MyMethodInterceptor()); UserServiceImpl userService = (UserServiceImpl)enhancer.create();Copy the code

What is cglib ASM woven into?

The Intercept method is woven into the proxy class so that the corresponding enhancement logic is called when the proxy method of the proxy class is used, and the Intercept method can write how to enhance and how the original method is called. The corresponding proxy method in the proxy class has been changed (the JDK dynamic proxy makes the same changes to the method).

Does Cglib need the original object

JDK dynamic proxies, which use traditional reflection when calling the original method of the target class, need to be called from the original object. Cglib dynamic proxies, on the other hand, are implemented by calling methods on superclass objects from proxy objects, so the original object is not required

FastClass mechanism

This means that we normally call methods from instances like a.dd ().

Method. Invoke (obj, args) uses this method. This is a complicated process.

Invoke (obj, args); invoke(obj, args); invoke(obj, args); It’s like you’re calling a method directly.

switch (index) {
		case 1:
			a.add();
			return null;
		case 2:
			a.delete();
			return null;
		}
Copy the code