Abstract:Java memory dump is a snapshot of the JVM’s memory at runtime. It can be used to analyze whether there is memory waste, check whether memory management is proper, and find out the cause of problems when OOM occurs. What does dump look like?

JVM dump

Java memory dump is a snapshot of the JVM’s memory at runtime. It can be used to analyze whether there is memory waste, check whether memory management is proper, and find out the cause of problems when OOM occurs. What does dump look like? Let’s take it one step at a time

Get the JVM dump file

Dump files can be obtained in active or passive ways

I. Active mode: 1. Use jmap, which is the most common mode: jmap-dump :[live],format=b,file= 2. Using JCMD, JCMD gC. heap_dump 3. Using VisualVM, can be interface operation for memory dump 4. Through JMX

MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
mxBean.dumpHeap(filePath, live);Copy the code

Reference (www.baeldung.com/java-heap-d)…

Ii. Passive mode: passive way is our usual OOM events, by setting the parameter – XX: XX: + HeapDumpOnOutOfMemoryError – HeapDumpPath =

Dump File Analysis

Structure diagram

The structure,

A dump file is a heap memory mapping consisting of a file header and a series of content blocks

The file header

It consists of Musk, version, identifierSize, and time

Musk: 4 bytes with ‘J’, ‘A’, ‘V’, ‘A’ for JAVA

2. Version: specifies multiple bytes, including the following three byte values

1.0\0 "PROFILE"."PROFILE 1.0.1\0"."PROFILE 1.0.2\0"Copy the code

3. IdentifierSize: four byte numbers, either 4 or 8, indicating the number of bytes used in a reference

4. Time: indicates the generation time of the dump file in 8 bytes

There are two types of member variables in a Java class

  1. Basic types (eight basic types), which occupy a fixed number of bytes and need to initialize and allocate space for each object they generate
  2. Is a reference type, which represents an object. There is only one reference in the class, the reference is just a number, the size of the space is identifierSize, the referenced object is going to be defined in another place in the heap for example a class
public class Person { private int age; //4 bytes private String name; //identifierSize byte private double weight; / / 8 byte}Copy the code

When we’re in new Person() it needs to claim a space that is the size of the object header +4+identifierSize+8 bytes

Instrumentation: The JDK provides a tool to test the size of the memory used by objects, but Instrumentation cannot be directly referenced to the agent to define a Premain class, javac premain.java

//Premain.java public class Premain { public static java.lang.instrument.Instrumentation inst; public static void premain(String args, java.lang.instrument.Instrumentation inst) { Premain.inst = inst; }}Copy the code

Write a Manifest file

Manifest.mf manifest-version: 1.0 premain-class: Premain can-re-classes:true
Can-Retransform-Classes: trueCopy the code

packaging

jar -cmf manifest.mf premain.jar Premain.classCopy the code

Define an execution class, javac PersonTest.java

//PersonTest.java
public class PersonTest {
    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("Premain");
        if(clazz ! = null) { Person p = new Person(); java.lang.instrument.Instrumentation inst = (java.lang.instrument.Instrumentation)clazz.getDeclaredField("inst").get(null);
            System.out.println("person size:[" + inst.getObjectSize(p) + "]B");
            System.out.println("class size:[" + inst.getObjectSize(p.getClass()) + "]B"); }}}Copy the code

With the agent to perform

java -javaagent:premain.jar PersonTestCopy the code

Results:

person size:[32]B
class size:[504]BCopy the code

Piece of content

Each block is made up of bulk and block

bigger

The size is defined by the block type of 1 byte, the time of 4 bytes, and the length of 4 bytes. There are generally five types of type: string, class, stack frame, stack, and dump blocks

  1. String, identifierSize byte string ID, followed by (length-identifiersize) byte string content.
  2. Class, consisting of the class sequence of 4 bytes (used in stack frame), the class ID of 4 bytes (used for class resolution), the sequence ID of 4 bytes (not currently used), and the class name ID of 4 bytes
  3. Stack frame, consisting of identifierSize byte frame ID,identifierSize byte method name ID,identifierSize byte class name ID,4 byte class sequence, The line number of four bytes
  4. Stack, consisting of the stack number of 4 bytes, thread number of 4 bytes, frame number of 4 bytes, followed by a number of identifierSize byte frame ids
  5. Dump blocks are the contents of all objects. Each object consists of a byte subtype and the contents of the object. There are 6 subtypes: GC root, thread object, class, object, primitive array, and object array

gc root

Gc root has four structures and eight types

  1. IdentifierSize Specifies the object ID of each byte, the type being SYSTEM_CLASS,BUSY_MONITOR, or UNKNOWN
  2. IdentifierSize Object ID of one byte, thread SERIAL number of four bytes, type NATIVE_STACK, THREAD_BLOCK
  3. IdentifierSize Object ID of 4 bytes, thread serial number of 4 bytes, stack frame depth of 4 bytes, type JAVA_LOCAL, NATIVE_LOCAL
  4. IdentifierSize Specifies the object ID of the byte. Global refId (unused) is the byte of identifierSize. The type is NATIVE_STATIC

Gc Root schematic

The GC root is the source of the garbage collection trace, and each GC root points to an initial object. Objects that cannot be traced are collected

Each class is a GC root thread stack. Method parameters and local variables in the thread are GC root. Each object is a GC root system reserved object, and each object is a GC root

Class object

1. Basic Information:

  1. IdentifierSize Specifies the id of the class object in bytes
  2. Stack sequence number of 4 bytes,
  3. IdentifierSize Specifies the parent object ID of a byte.
  4. IdentifierSize classLoader object ID in bytes,
  5. IdentifierSize Byte Signer object ID,
  6. IdentifierSize Protection domain object ID in bytes,
  7. IdentifierSize Byte reserved ID1 and ID2,
  8. Class instance object size of 4 bytes,
  9. Number 2 byte constants, followed by each constants, 2 byte subscript, type of constant 1 byte, and a number of the contents of a byte, content depends on the type (Boolean/byte to 1 byte, char/short for two byte, Float /int 4 bytes, double/long 8 bytes, reference type identifierSize 8 bytes)
  10. The number of static variables in 2 bytes, followed by each static variable, identifierSize the variable name ID of 1 byte, the variable type of 1 byte, and the contents of several bytes, depending on the type (see section 9 of Basic information for class objects)
  11. Number of member variables in 2 bytes, followed by each member variable, identifierSize variable name ID in 1 byte, variable type in 1 byte

2, description: (1) class inside the constant is not used in many places, so the number of constants is generally 0 (2) class static variable name type and value is placed in the class object, the name and type of member variables are also placed in the class object, but the value of the instance is placed in the instance object

Instance objects

1. Basic Information:

  1. IdentifierSize Instance object ID of one byte
  2. Stack sequence number of 4 bytes
  3. IdentifierSize Class ID of one byte
  4. The number of bytes occupied by four bytes
  5. The value of the instance variable

2. Description:

  1. The values of the instance are the values of the member variables of the instance object, in the order of the values of the variables of the current class, in the order described in Article 11 of basic information for class objects, and then the values of the variables of the parent class
  2. The value of a variable has a default value for the basic type, and the default value for the reference type is 0, occupying the number of bytes (see section 9 of Basic Information for Class Objects).

Array of primitive types

1. Basic Information:

  1. IdentifierSize Array object ID of one byte
  2. Stack sequence number of 4 bytes
  3. The array length is 4 bytes
  4. The element type is 1 byte
  5. A list of values for the element

2. Description:

  1. The value of the element (see section 9 of Basic information for Class objects)

An array of objects

1. Basic Information:

  1. IdentifierSize Array object ID of one byte
  2. Stack sequence number of 4 bytes
  3. The array length is 4 bytes
  4. IdentifierSize Specifies the element class ID in bytes
  5. A list of values for the element

Memory allocation

When a thread to start process will generate a thread stack to system memory Whenever a method call, will be to the medium voltage into a stack frame, when, after a method call stack frame will exit in the process of running, the object if there is a new operation, the process will apply to the heap area a piece of memory About the details of the runtime memory, You can look for relevant information

Memory reclamation rule

If an object is not reachable by riding a GC root reference, then the object may be covered by the reclaim object collection rule

  1. Instance attributes are referenced by the instance, and can only be reclaimed if the instance is reclaimed (strong references only)
  2. Class objects are referenced by instances, and a class can only be reclaimed if all instances of a class have been reclaimed
  3. The parent class, the classLoader, the Signer, and the Protection domain are referenced by the class and can only be reclaimed if the class is reclaimed
  4. The scope of a local variable (in the thread stack) is a curly brace
public void test(){ Object a = new Object(); //obj 1 Object b = new Object(); //obj 2 { Object c = new Object(); //obj 3 a = null; //obj 1 can be collected}//obj 3 can be collected}//obj 2 can be collectedCopy the code

Analysis Tool Introduction

To analyze the dump file, we can use the Jhat tool provided in the JDK

jhat xxx.dumpCopy the code

Jhat loads and parses the xxx.dump file and starts a simple Web service with a default port of 7000 that allows you to view some statistics in memory through a browser

General usage

1. Open the browser HTTP :/127.0.0.1:7000

Features are listed, including an overview of the individual classes under the Package, and navigation of the individual features

2, click page heap memory statistics

There’s a table, the type of object, the number of instances, how much memory it takes up, and you can see which type of object takes up the most memory

3. Click the name of the class that consumes too much memory to view the class details

It mainly shows the size of each instance below the class, as well as some link navigation

4, Click References summary by type

If there are too many objects of a type, there are probably too many objects of the class that references it

Basically a few simple page queries, combined with the original code, can initially locate memory leaks

In summary, the dump file structure is relatively simple. It is very useful for analyzing the execution of threads. It is also one of the advanced skills that every Java programmer must master.


Click to follow, the first time to learn about Huawei cloud fresh technology ~