JVM Part 2: Performance Monitoring and Tuning_03_JVM Monitoring and Diagnostic Tools-GUI_Silicon Valley

Table of contents

Article directory

01-tool overview

Basic information related to the performance of the target Java application can be obtained using the command-line tools or combinations from the previous chapter, but they have the following limitations:

  1. Method-level analysis data cannot be obtained, such as the call relationship between methods, the number of calls and call time of each method, etc. (this is critical for locating application performance bottlenecks).
  2. The user is required to log in to the host machine where the target Java application is located, which is not very convenient to use.
  3. The analysis data passes through the terminal data, and the result display is not intuitive enough.

To this end, JDK provides some memory leak analysis tools, such as jconsole, jvisualvm, etc., to assist developers in locating problems, but these tools often do not meet the needs of quick locating. So here we introduce relatively more and richer tools.

Graphical Comprehensive Diagnostic Tool

  • JDK comes with tools
    • jconsole: Visual monitoring tool that comes with JDK. View the running profile of Java applications, monitor heap information, permanent generation (or metaspace) usage, class loading, etc. Location: jdk\bin\jconsole.exe
    • Visual VM: Visual VM is a tool that provides a visual interface for viewing detailed information about Java technology-based applications running on a Java virtual machine. Location: jdk\bin\jvisualvm.exe
    • JMC: Java Mission Control, built-in Java Flight Recorder. It can collect performance data of Java Virtual Machine with extremely low performance overhead.
  • third party tools
    • MAT: MAT (Memory Analyzer Tool) is an Eclipse-based memory analysis tool. It is a fast, feature-rich Java heap analysis tool that can help us find memory leaks and reduce memory consumption.
    • JProfiler: commercial software, need to pay. Powerful.
    • Arthas: Alibaba's open source Java diagnostic space. Loved by developers.
    • Btrace: Java runtime tracing tool. Information such as specified method calls, constructor calls, and system memory can be traced without downtime.

02-JConsole

Basic overview

  • Starting from Java5, the Java monitoring and management console that comes with the JDK.
  • It is a GUI performance monitoring tool based on JMX (Java management extensions) for monitoring memory, threads and classes in the JVM.

Official tutorial: https://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html

start up

  • In the jdk/bin directory, start the jconsole.exe command
  • Open the DOS window and directly enter jconsole

three connection methods

Local

​ Use JConsole to connect to a JVM running on the local system, and the user who executes the program and runs JConsole needs to be the same user. JConsole uses filesystem authorization to connect to the server via RMI that is linked to the platform's MBeans. This ability to monitor from a local connection is only available in Sun's JDK.

Remote

Connect to a JMX agent through the RMI connector using the following URL, service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi. In order to establish a connection, JConsole needs to set mx.remote.credentials in the environment variable to specify the user name and password for authorization.

Advanced

​ Use a special URL to connect to the JMX agent. In general, use your own custom connector instead of the connector provided by RMI to connect to the JMX agent, or an application that implements JMX and JMX Rmote using JDK1.4

main effect

1. Overview

image-20221003144527534

2. Memory

image-20221003144556699

3. Thread

image-20221003144613851

4, Overview

image-20221003144649961

03-Visual VM

The difference between jvisualvm and visual vm

There is no difference, except that visual vm is downloaded separately, and jvisualvm comes with JDK

Basic overview

  • Visual VM is a powerful all-in-one visualization tool for troubleshooting and performance monitoring.
  • It integrates multiple JDk command-line tools, using Visual VM can be used to display the virtual machine process and process configuration and environment information (jps, jinfo), monitor the application's CPU, GC, heap, method area and thread information (jstat , jstack), etc., even instead of JConsole
  • After JDK 6 Update 7, Visual VM is released as part of JDK (VisualVM is in the JDK/bin directory)
  • Alternatively, Visual VM can also be installed as a standalone software:

Home page: https://visualvm.github.io/index.html

interface:

image-20221003150100049

plugin installation

A major feature of Visual VM is that it supports plug-in expansion, and plug-in installation is very convenient. We can download the plug-in file *.nbm offline, and then add the downloaded plug-in under the downloaded interface in the Plugin dialog box. Plugins can also be installed online under the Available Plugins page. (It is recommended to install: VisualGC)

​ Plug-in address: https://visualvm.github.io/pluginscenters.html

​ It can also be installed directly in Visual VM, Tools -> Plugins -> Available Plugins -> Select Plugins to Install

connection method

local connection

Monitor the CPU, class, thread, etc. of the local Java process

Remote Connection

1- Determine the ip address of the remote server

2-Add JMX (specifically monitor which Java process of the remote server through JMX technology)

3- Modify the bin/catalina.sh file to connect to the remote tomcat

4- Add jmxremote.access and jmxremote.password files in .../conf

5- Change the server address to the public network ip address

6-Set Alibaba Cloud security policy and firewall policy

7-Start tomcat, view tomcat startup log and port monitoring

8-Enter the port number, user name, and password in JMX to log in

The main function

1. Generate/read heap memory snapshot

image-20221003151919007

Note: When the process stops, the snapshot will be lost. If you want to save it, you need to save the snapshot.

Save the dump file:

image-20221003152042335

2. View JVM parameters and system properties

3. View the running virtual machine process

4. Generate/read thread snapshot

image-20221003152512227

5. Real-time monitoring of program resources

6. Other functions

  • JMX proxy connection
  • Remote Environmental Monitoring
  • CPU analysis and memory analysis

04-Eclipse MAT

Basic overview

MAT (Memory Analyzer Tool) tool is a powerful Java heap memory analyzer. Can be used to find memory leaks and view memory consumption.

​ MAT is developed based on Eclipse, not only can be used alone, but also can be embedded in Eclipse as a plug-in. It is a free performance analysis tool that is very convenient to use.

Download address: https://www.eclipse.org/mat/previousReleases.php

​ You can download version 1.11.0

​ Just make sure that JDK is installed on the machine and relevant environment variables are configured, MAT can start normally.

Get the dump file

dump file content

MAT can analyze heap dump files. When performing memory analysis, as long as the hprof file reflecting the memory image of the current device is obtained, the current memory information can be visually seen through MAT development.

​ Generally speaking, these memory information include:

  • All object information, including object instances, member variables, basic type values ​​​​stored in the stack, and reference values ​​​​of other objects stored in the heap.
  • All class information, including classloader, class name, parent class, static variables, etc.
  • GCRoot to all reference paths of these objects
  • Thread information, including the call stack of the thread and the thread local variable (TLS) of this thread

two points

Note 1: Disadvantages

​ MAT is not a universal tool, it cannot handle all types of heap storage files. However, the more mainstream manufacturers and formats, such as the HPROF binary heap dump files used by Sun, HP, and SAP, and the PHD heap storage files of IBM, can all be parsed very well.

Description 2:

​ The most attractive thing is that it can quickly generate a memory leak table for developers , which is convenient for locating and analyzing problems. Although MAT has such a powerful function, memory analysis is not as simple as one-click completion. Many memory problems still need to be discovered through experience and intuition from the information displayed to us by MAT.

Get the dump file

  1. via jmap
  2. By configuring JVM parameters
    • -XX:+HeapDumpOnOutOfMemoryError: When the program OOM occurs, export the current heap snapshot of the application.
    • -XX:HeapDumpPath=<filename.hprof>: You can specify the save location of the heap snapshot.
  3. Dump files can be exported through VisualVM

It is almost impossible to analyze it online in a production environment, and most of them use offline analysis, so using jmap+MAT tools is the most common combination.

Analyze the heap dump file

file in the upper left corner -> Open Heap Dump -> select the dump file

image-20221003185121365

Leak Suspects Report

  • Automatically analyze the main causes of current memory leaks through MAT

Component Report

  • Component report, which analyzes objects belonging to a common root package or class loader

Re-open previouslu run reports

  • Reopen previous analysis results

Main interface:

[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-WkOr8xkl-1665851221026) (C:\Users\86156\AppData\Roaming\Typora\typora-user-images\ image-20221003191740377.png)]

histogram

​ MAT's histogram is the same as jmap's -histo subcommand, which can display the number of instances of each class and the sum of Shallow heap of these instances. However, the histogram of MAT can also calculate retained heap, and supports sorting based on the number of instances or retained heap (the default is shallow heap).

In addition, MAT can also group the classes in the histogram by superclass, class loader or package name.

​ When a class is selected, the Instpector window in the upper left corner of the MAT interface will display information about the Class instance of the class, such as the class loader.

Shows the number of instances of each class and the sum of Shallow heap or Retained heap of these instances

use:

image-20221003193126779

Specific content:

image-20221003193207206

image-20221003195110032

image-20221005164602538

View GC Roots to exclude virtual/soft/weak references

image-20221005165058040

thread overview

  • View the Java threads in the system
  • View information about local variables

View by:

image-20221005170505922

Get the relationship between objects that apply to each other

  • with outgoing references to see which objects are referenced

  • Which objects are referenced by with incoming references

image-20221005180846116

Shallow and Deep Heaps

shallow pile

Shallow Heap refers to the memory consumed by an object. In a 32-bit system, an object reference will occupy 4 bytes, an int type will occupy 4 bytes, a long type variable will occupy 8 bytes, and each object header will occupy 8 bytes. Depending on the format of the heap snapshot, the size of the object may be aligned to 8 bytes.

​Taking String as an example, 2 int values ​​occupy 8 bytes in total, object reference occupies 4 bytes, and object header occupies 8 bytes, totaling 20 bytes, and aligns with 8 bytes, so it occupies 24 bytes. (in jdk7)

int hash32 0
int hash 0
ref value “”

These 24 bytes are the shallow heap size for String objects. It has nothing to do with the actual value of String, regardless of the length of the string, the shallow heap size is always 24 bytes.

The object header represents the object header of the object created according to the class, and the size of the object must be aligned to 8 bytes

Deep heap (retained heap)

​Retained Set:

​ The retained set of object A refers to all object combinations (including object A itself) that can be released after object A is garbage collected, that is, the retained set of object A can be artificially accessed only directly or indirectly through object A A collection of all objects to . In layman's terms, it refers to the collection of objects held only by object A.

​Deep heap (retained heap):

​ Deep heap refers to the sum of the shallow heap sizes of all objects in the object's retain set.

​ Note: The memory occupied by the shallow heap object itself does not include the size of its internal reference objects. The deep heap of an object refers to the sum of the shallow heaps of all objects that can only be accessed (directly or indirectly) through the object, that is, the real space that can be released after the object is recycled .

Supplement: the actual size of the object

Another commonly used concept is the actual size of an object. Here, the actual size of an object is defined as the shallow stack size of all objects that an object can touch, which is what we call the object size in the usual sense. Compared with deep heap, it seems that this is more intuitive and accepted in daily development, but in fact, this concept has nothing to do with garbage collection

​ The figure below shows a simple object reference diagram, object A references C and D, and object B references C and E. Then the shallow heap size of object A is only A itself, excluding C and D, and the time size of A is the sum of A, C, and D. However, the sum of the deep heap size of A and A and D is not within the deep heap range of object A because object C can also be accessed through object B.

image-20221005183856739

practise

Look at the picture to understand Retained Size

image-20221005185131080

In the figure above, GC Roots directly references two objects, A and B.

A's shallow heap: A

A's deep heap: A

B's shallow heap: B

B's deep heap: B, C, does not contain D objects, because D objects are directly referenced by GC Roots.

What if GC Roots do not refer to D objects?

image-20221005185925784

B's deep heap: B, C, D, because D is not directly referenced by GC Roots

Case Study: StudentTrace

code:

/**
 * -XX:+HeapDumpBeforeFullGC -XX:HeapDumpPath=d:\student.hprof
 */
public class StudentTrace {
    
    
  static List<WebPage> webPages = new ArrayList<>();

  public static void createWebPages() {
    
    
    for (int i = 0; i < 100; i++) {
    
    
      WebPage wp = new WebPage();
      wp.setUrl("http://www." + Integer.toString(i) + ".com");
      wp.setContent(Integer.toString(i));
      webPages.add(wp);
    }
  }

  public static void main(String[] args) {
    
    
    createWebPages(); // 创建了100个网页
    // 创建3个学生对象
    Student st3 = new Student(3, "Tom");
    Student st5 = new Student(5, "Jerry");
    Student st7 = new Student(7, "Lily");

    for (int i = 0; i < webPages.size(); i++) {
    
    
      if (i % st3.getId() == 0) {
    
    
        st3.visit(webPages.get(i));
      }
      if (i % st5.getId() == 0) {
    
    
        st5.visit(webPages.get(i));
      }
      if (i % st7.getId() == 0) {
    
    
        st7.visit(webPages.get(i));
      }
    }
    webPages.clear();
    System.gc();
  }

}

class Student {
    
    
  private int id;
  private String name;
  private List<WebPage> history = new ArrayList<>();

  public int getId() {
    
    
    return id;
  }

  public Student(int id, String name) {
    
    
    super();
    this.id = id;
    this.name = name;
  }

  public void visit(WebPage wp) {
    
    
    if (wp != null) {
    
    
      history.add(wp);
    }
  }
}

class WebPage{
    
    
  private String url;
  private String content;

  public String getUrl() {
    
    
    return url;
  }

  public void setUrl(String url) {
    
    
    this.url = url;
  }

  public String getContent() {
    
    
    return content;
  }

  public void setContent(String content) {
    
    
    this.content = content;
  }
}

The shallow heaps of the three objects are all 24

image-20221005192622708

Analyzing a shallow heap size of 24 Source:

private int id; // 4
private String name; // 4 
private List<WebPage> history = new ArrayList<>(); // 4

​ int occupies 4 bytes, two references 4+4 occupy 8 bytes, object header occupies 8 bytes, a total of 20 bytes are aligned to 8, and a total of 24 bytes are occupied

Analyze the source of the elementData deep heap size 1288 of "Lily"'s history (I feel that there is a problem with what I said, and I need to confirm it again)

image-20221005200938437

15 webpages

The total size of the webpage is: 144 + 14 *152 = 2272 bytes -> is the actual size of elementData.

How is the deep heap size of elementData 1288 bytes calculated?

There are 7 numbers that are divisible by 7 and divisible by 3, and divisible by 7 and divisible by 5: 0, 21, 42, 63, 84, 35, and 70.

2272 - 144 (the size of index 0 is 144) - 6 * 152 = 1216 (bytes)

Calculating 1288 - 1216 is still 72 bytes short.

What are these 72 bytes?

15 elements of elementData * 4 bytes = 60 bytes

60 + 8 bytes of the object header + 4 (occupancy of the array itself) = 72 bytes

Dominator Tree

​ The concept of a dominator tree comes from graph theory.

MAT provides an object graph called a dominator tree. The dominance tree reflects the dominance relationship between object instances. Object A is said to dominate object B if all paths to object B pass through object A in the object reference graph . Object A is considered to be the immediate dominator of object B if object A is the closest dominator to object B. The dominator tree is based on the references between objects, and it has the following basic properties.

  • The subtree of object A (the collection of all objects dominated by object A) represents the retained set of object A (retained set), that is, the deep heap.
  • If object A dominates object B, then the immediate dominator of object A also dominates object B.
  • The edges of the dominator tree and the edges of the object reference graph are not direct objects.

​As shown in the figure below: the graph represents the object reference graph, and the right graph represents the dominator tree corresponding to the left graph. Objects A and B are directly dominated by root objects. Since the path to object C can pass through A or B, the direct dominator of object C is also the root object. Object F and object D refer to each other, because all paths to object F must pass through object D, so object D is the direct dominator of object F. All paths to object D must pass through object C. Even if the reference from object F to object D is triggered from the root node, it also passes through object C. Therefore, the direct dominator of object D is object C.

image-20221005205158830

Similarly, object E dominates object G. Those who reach object H can pass through object D or object E, so neither object D nor E can dominate object H, but can reach both D and E through object C, so object C is the direct dominator of object H.

​ In MAT, click the object dominator tree button on the toolbar to open the object dominator tree view

image-20221005210454458

view thread

image-20221005210717791

There are only 8 Lily sites that can be cleared, which means that if Lily's objects are recycled, only these 8 sites can be recycled

image-20221005210955389

Case: Tomcat heap overflow analysis

illustrate

Analysis process

Supplement 1 Talking about memory leaks again

Understanding and classification of memory leaks

What is a memory leak

image-20221005215912269

​ The reachability analysis algorithm to determine whether an object is no longer used is essentially to determine whether an object is still referenced. So in this case, due to the different implementation of the code, there will be many kinds of memory leak problems (making the JVM mistakenly think that the object is still in reference and cannot be recycled, resulting in memory leaks).

Understanding of memory leaks

​ Strictly speaking, only when the objects are no longer used by the program, but the GC cannot reclaim them, is it called a memory leak.

​ But in the actual situation, in many cases, some bad timing (or negligence) will cause the life cycle of the object to become very long and even lead to OOM, which can also be called "memory leak" in a broad sense

image-20221005221243063

​ Object X refers to object Y, and the life cycle of X is longer than that of Y;

​ Then when the life cycle of Y ends, X still refers to Y. At this time, the garbage collector will not recycle the object Y;

​ If object X still refers to objects A, B, and C with relatively short life cycles, and object A also refers to objects a, b, and c, this may cause a large number of useless objects that cannot be recycled, and then occupy memory resources, resulting in memory loss. Memory leaks until out of memory.

The relationship between memory leaks and memory overflow

(1) Memory leak (memory leak)

If the memory is used up and not released, for example, there is a total of 1024M of memory, and the allocated memory of 512M has not been reclaimed, so the usable memory is only 521M, as if part of it has been leaked;

(2) Memory overflow (out of memory)

When applying for memory, there is not enough memory available;

It can be seen that the relationship between memory leaks and memory overflow: the increase of memory leaks will eventually lead to memory overflow.

Classification of leaks

Occurs often : the code with the memory leak will be executed multiple times, and each time it is executed, a block of memory will be leaked;

**occasional:** will only happen under certain circumstances;

**One-off:**The method with a memory leak will only be executed once;

**Implicit leak:** It keeps occupying the memory and does not release it until the execution ends; strictly speaking, this is not considered a memory leak, because it is finally released.

8 Situations of Memory Leaks in Java

1. Static collection class

​ Static collection classes, such as HashMap, LinkedList, etc. If these containers are static, then their life cycle is the same as that of the JVM program, and the objects in the container will not be released before the program ends, causing memory leaks. Simply put, long-lived objects hold references to short-lived objects. Although short-lived objects are no longer used, they cannot be recycled because long-lived objects hold references to them.

public class MemoryLeak {
    
    
	static List list = new ArrayKList();
  
  public void oomTest() {
    
    
    Object obj = new Object(); // 局部变量
    list.add(obj);
  }
}

2. Singleton mode

​ The singleton mode is similar to the reason why static collections cause memory leaks. Because of the static nature of singletons, its life cycle is as long as the life cycle of the JVM, so if the singleton object holds a reference to an external object, then the external The object will not be recycled, which will cause a memory leak.

3. The inner class holds the outer class

​ The inner class holds the outer class, if a method of an instance object of the outer class returns an instance object of the inner class.

​ This memory class object has been referenced for a long time, even if the external instance object is no longer used, but because the internal class holds the instance object of the external class, the external class object will not be garbage collected, which will also cause a memory leak.

4. Various connections, such as database connection, network connection and IO connection, etc.

​ In the process of operating the database, you first need to establish a connection to the database. When it is no longer in use, you need to call the close method to release the connection to the database. Only after the connection is closed, the garbage collector will reclaim the corresponding object.

​ Otherwise, if the Connection, Statement or ResultSet is not explicitly closed during the process of accessing the database, a large number of objects will not be reclaimed, resulting in memory leaks.

5. Unreasonable scope of variables

Generally speaking, the scope of a variable's definition is greater than its scope of use, which is likely to cause memory leaks. On the other hand, if the object is not set to null in time, it is likely to cause a memory leak.

6. Change the hash value

​ Change the hash value. After an object is stored in the HashSet collection, the fields in the object that participate in the calculation of the hash value cannot be modified.

​ Otherwise, the hash value after the object is modified is different from the hash value when it was originally stored in the HashSet collection. In this case, use the current reference of the object as a parameter in the contains method to retrieve the object in the HashSet collection in time , will also return the result that the object cannot be found, which will also result in the inability to delete the current object from the HashSet collection alone, resulting in a memory leak.

​ This is why String is set as an immutable type. We can safely store String in HashSet, or use String as the key value of HashMap;

7. Cache leaks

​ Another common source of memory leaks is caches. Once an object reference is placed in the cache, it is easy to forget. For example: when the previous project was launched for the first time, the application startup was extremely slow, because the code would load the data of a table into the cache (memory), the test environment only had a few hundred pieces of data, but the production environment had millions of data .

​ For this problem, WeakHashMap can be used to represent the cache. The characteristic of this kind of Map is that when the key has no other references except its own reference to the Key, the map will automatically lose this value.

8. Listeners and callbacks

A third common source of memory leaks is listeners and other callbacks, which can accumulate if clients register callbacks in your implemented API without explicit cancellation.

The best way to ensure that the callback is immediately garbage collected is to save only weak references to it, e.g. save them as keys in a WeakHashMap.

Supplement 1 Case Analysis of Memory Leaks

the case

Case code:

public class Stack {
    
    
  private Object[] elements;

  private int size = 0;

  private static final int DEFAULT_INITIAL_CAPACITY = 16;

  public Stack() {
    
    
    elements = new Object[DEFAULT_INITIAL_CAPACITY];
  }

  public void push(Object e) {
    
    
    ensureCapacity();
    elements[size++] = e;
  }

  public Object pop() {
    
    
    if (size == 0) {
    
    
      throw new EmptyStackException();
    }
    return elements[--size];
  }

  private void ensureCapacity() {
    
    
    if (elements.length == size) {
    
    
      elements = Arrays.copyOf(elements, 2 * size + 1);
    }
  }
}

analyze

​ The above program has no obvious errors, but this program has a memory leak. As the GC activity increases, or the memory usage continues to increase, the performance of the program will decrease. In severe cases, it can lead to memory leaks, but Such failures are relatively rare.

​ The main problem of the code is the pop function, which is shown below through this diagram

​ Assume that the stack has been growing, as shown in the figure below

image-20221006205539711

​ When a large number of pop operations are performed, because the reference is not emptied, the gc will not release it, as shown in the figure below

image-20221006205621683

​ As can be seen from the above figure, if the stack grows first and then shrinks, the objects popped from the stack will not be garbage collected. Even if the program no longer uses these objects in the stack, they will not be recycled. Because there are still references to these objects in the stack, commonly known as expired references , this memory leak is very hidden.

Solution

public Object pop() {
    
    
  if (size == 0) {
    
    
    throw new EmptyStackException();
  }
  Object result = elements[--size];
  elements[size] = null;
  return result;
}

Once no longer used, clear these references and make the references empty

image-20221006210346361

Supplement 2 Support querying object information using OQL language

SELECT clause

​ MAT supports a SQL-like query language OQL (Object Query Language). OQL uses SQL-like syntax to search and filter objects in the heap.

select * from java.util.ArrayList

Use the "OBJECTS" keyword to display the items in the returned result set as objects.

SELECT v.elementData FROM java.util.ArrayList v 

SELECT objects v.elementData FROM java.util.ArrayList v 

In the Select clause, use the "AS RETAINED SET" keyword to get a retained set of the resulting object.

SELECT AS RETAINED SET * FROM com.atguigu.mat.Student

The "DISTINCT" keyword is used to remove duplicate objects in the result set.

SELECT DISTINCT OBJECTS classof(s) FROM java.lang.String s

FROM clause

The From clause is used to specify the scope of the query, which can specify a class name, a regular expression, or an object address.

SELECT * FROM java.lang.String s

Use regular expressions to limit the search scope and output all instances of all classes under the com.atguigu package

SELECT * FROM "com\.atguigu\..*"

Search using the address of the class. The advantage of using the address of the class is that it can distinguish the same type loaded by different ClassLoaders.

select * from 0x37a0b4d

WHERE child clause

Where clause is used to specify the query condition of OQL. OQL queries will only return objects that satisfy the conditions specified in the Where clause. The format of the Where clause is very similar to traditional SQL.

Returns a char array of length greater than 10.

SELECT *FROM Ichar[] s WHERE s.@length>10

Returns all strings that contain a substring of "java", using the "LIKE" operator whose operation parameter is a regular expression.

SELECT * FROM java.lang.String s WHERE toString(s) LIKE ".*java.*"

Returns all strings whose value fields are not null, using the "=" operator.

SELECT * FROM java.lang.String s where s.value!=null

Returns all Vector objects whose array length is greater than 15 and whose deep heap is greater than 1000 bytes.

SELECT * FROM java.util.Vector v WHERE v.elementData.@length>15 AND v.@retainedHeapSize>1000

Built-in Objects and Methods

In OQL, you can access the properties of objects in the heap, and you can also access the properties of proxy objects in the heap. When accessing the properties of objects in the heap, the format is as follows, where alias is the object name:

[ . ] . .

Access the path property of the java.io.File object, and further access the value property of path:

SELECT toString(f.path.value) FROM java.io.File f

Displays the contents, objectid, and objectAddress of a String object.

SELECT s.toString(),s.@objectId, s.@objectAddress FROM java.lang.String s

Displays the length of the java.util.Vector internal array.

SELECT v.elementData.@length FROM java.util.Vector v

Display all java.util.Vector objects and their subtypes

select * from INSTANCEOF java.util.Vector

Display all java.util.Vector objects and their subtypes

select * from INSTANCEOF java.util.Vector

JProfile

Basic overview

​ When running Java, sometimes you want to test the memory usage during runtime. At this time, you need to use the test tool to check. There is an Eclipse Memory Analyzer tool (MAT) plug-in in eclipse that can be tested, and there is also such a plug-in in IDEA, which is JProfiler.

​ JProfiler is a Java application performance diagnostic tool developed by ej-technologies. Powerful, but charges.

​ Official download address: https://www.ej-technologies.com/download/jprofiler/files

Features:

  • Easy to use, friendly interface operation (simple and powerful)
  • Small impact on the application being analyzed (template provided)
  • CPU, Thread, Memory analysis functions are especially powerful
  • Supports analysis of jdbc, noSql, jsp, servlet, socket, etc.
  • Support analysis in multiple modes (offline, online)
  • Support monitoring local and remote JVM
  • Cross-platform, with multiple operating system installation versions

The main function

1. Method call

Analysis of method calls can help you understand what your application is doing and find ways to improve its performance

2- Memory allocation

By analyzing objects on the heap, reference chains and garbage collection, it can help you fix memory leaks and optimize memory usage

3- Threads and locks

JProfiler provides a variety of analysis views for threads and locks to help you find multi-threading problems

4- Advanced Subsystem

Many performance problems occur at a higher semantic level. For example, for a JDBC call, you might want to find out which SQL statement executes the slowest. JProfiler supports integrated analysis of these subsystems

Installation and configuration (omitted)

Specific use

Data collection method

JProfier data collection methods are divided into two types: Sampling (sample collection) and Instrumentation (reconstruction mode)

  • Instrumentation : This is the full-featured mode of JProfiler. Before the class is loaded, JProfier writes the relevant function code into the bytecode of the class to be analyzed, which has a certain impact on the running jvm.
    • Advantages: powerful. In this setup, the call stack information is accurate.
    • Disadvantage: If there are many classes to be analyzed, it will have a great impact on the performance of the application, and the CPU overhead may be high (depending on the control of Filter). Therefore, this mode is generally used in conjunction with Filter to analyze only specific classes or packages
  • Sampling : Similar to sample statistics, the information in the method stack in each thread stack is counted every certain time (5ms).
    • Advantages: The CPU overhead is very low, and the application has little impact (even if you do not configure any Filter)
    • Disadvantages: Some data/features cannot be provided (eg: method call times, execution time)

Note: JProfiler itself does not indicate the data collection type, the collection type here is the collection type for method calls. Because most of the core functions of JProfiler rely on the data collected by method calls, it can be directly considered as the data collection type of JProfiler.

Remote Sensing Monitoring Telemetries

image-20221006234757901

Memory View Live Memory

Live memory memory analysis: information about class/class instance. For example, the number and size of objects, the method execution stack of object creation, and the hotspots of object creation.

  • All Objects All Objects

    Displays a list of all loaded classes and the number of instances allocated on the heap. Only Java 1.5 (JVMTI) will display this view.

image-20221006235019654

  • Recorded Objects Recorded Objects

    View allocations of objects over a specific time period and record the call stack of the allocation.

  • Allocation Access Tree Allocation Call Tree

    Displays a request tree or method, class, package or J2EE component with annotated allocation information for a selected class.

  • Allocation Hot Spots

    Displays a list of methods, classes, packages, or J2EE components assigned to the selected class. You can label the current value and display the difference value. For each hotspot, its trace tree can be displayed.

  • Class Tracker Class Tracker

    The class trace view can contain any number of graphs showing instances and times of selected classes and packages

Analysis: what happens to objects in memory

  • Frequent creation of Java objects: infinite loop, too many loops
  • There are large objects: when reading a file, byte[] should be written while reading. If it is not written out for a long time, the byte[] will be too large
  • There is a memory leak

Notice:

  • The Size behind All Objects is the shallow heap size

Heap traversal heap walker

image-20221008224606941

image-20221008224904787

image-20221008224832616

View Diagram Reference Relationships

image-20221008225245798

image-20221008225156066

Main interface

image-20221008230031206

CPU view cpu views

JProfier provides different ways to record access trees to optimize performance and details. Threads or thread groups and thread states can be selected by all views. All views can be aggregated to different layers such as methods, classes, packages or J2EE components.

Access Tree Call Tree

Displays a cumulative top-down tree of all access queues recorded in the JVM. JDBC, JMS and JNDI service requests are annotated in the request tree. The request tree can be split according to the different needs of Servlet and JSP on the URL.

Hot SpotsHot Spots

Displays a list of methods that are consuming the most time. A backtracking tree can be displayed for each hotspot. The hotspot can be calculated in terms of method requests, JDBC, JMS and JNDI service requests, and in terms of URL requests.

Access graph Call Graph

Displays a graph of the access queue starting from the selected method, class, package or J2EE component.

Method Statistics Method Statistics

Displays call time details for recorded methods over time.

image-20221009225808446

thread view threads

JProfiler judges its running status through the monitoring of thread history, and monitors whether there is thread blocking. It can also display the methods managed by a thread in a tree display and analyze the thread.

Thread History Thread History

Displays a timeline of activity along with thread activity and thread state.

Thread Monitor Thread Monitor

Displays a list of all active threads and their current status.

Thread Dumps Thread Dumps

Show stack traces for all threads

Thread analysis is primarily concerned with three areas:

  1. The maximum number of threads for the web container. For example: Tomcat's thread capacity should be slightly greater than the maximum number of concurrency.
  2. thread blocking
  3. thread deadlock

Monitors & locks Monitors & locks

All threads hold locks and lock information

Watch the JVM's internal threads and view the status:

  • Deadlock detection graph Current Locking Graph: Displays the current deadlock graph in the JVM
  • Currently used detectors Current Monitors: Displays currently used detectors and includes their associated threads.
  • Locking History Graph Locking History Graph: Displays the locking history recorded in the JVM.
  • Historical monitoring records Monitor History: Displays the historical records of major waiting events and blocking events.
  • Monitor usage statistics Monitor Usage Statistics: Displays statistical monitoring data of group monitoring, threads and monitoring classes.

case analysis

Case 1

public class JProfilerTest {
    
    
    public static void main(String[] args) {
    
    
        while (true){
    
    
            ArrayList list = new ArrayList();
            for (int i = 0; i < 500; i++) {
    
    
                Data data = new Data();
                list.add(data);
            }
            try {
    
    
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}
class Data{
    
    
    private int size = 10;
    private byte[] buffer = new byte[1024 * 1024];//1mb
    private String info = "hello,atguigu";
}

Case 2

public class MemoryLeak {
    
    

    public static void main(String[] args) {
    
    
        while (true) {
    
    
            ArrayList beanList = new ArrayList();
            for (int i = 0; i < 500; i++) {
    
    
                Bean data = new Bean();
                data.list.add(new byte[1024 * 10]);//10kb
                beanList.add(data);
            }
            try {
    
    
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }

}

class Bean {
    
    
    int size = 10;
    String info = "hello,atguigu";
    static ArrayList list = new ArrayList();
}

Mark the running instance to determine what object caused it

image-20221009235446577

image-20221009235509712

image-20221009235602753

image-20221009235620287

found the reason

image-20221009235654267

Use images to show

image-20221009235821130

You can see that the byte array is finally referenced by the Bean

image-20221009235835993

06-Arthas

Basic overview

background

​ These two tools, Jvisualvm and Jprofile, are also relatively well-known in the industry. Their advantage is that they can see the performance data of each dimension on the graphical interface, and use them to conduct comprehensive analysis based on these data, and then determine where performance problems occur.

​ But these two tools also have shortcomings, and both of them must configure relevant monitoring parameters during the server-side project process. The tool then connects remotely to the project process to obtain relevant data. This will bring some inconvenience, for example, the network of the online environment is isolated, and the local monitoring tools cannot connect to the online environment at all. And commercial tools like JProfiler require payment.

​ So is there a tool that does not require remote connections, does not require configuration of monitoring parameters, and also provides rich performance monitoring data?

The answer is Alibaba's open source performance analysis magic Arthas (Alsace)

overview

Artha (Alsace) is Alibaba's open source Java diagnostic tool, which is very popular among developers. Troubleshoot problems online without restarting; dynamically track Java code: monitor JVM status in real time.

ArthasSupports JDK 6+, supports Linux/Mac/Windows, adopts command line interactive mode, and provides rich Tabauto- completion functions to further facilitate problem location and diagnosis.

When you encounter a similar problem and feel helpless, Arthas can help you:

  • Which jar package is this class loaded from? Why are various types of related Exception reported?
  • Why is the code I changed not executed? Could it be that I didn't commit? Branching wrong?
  • If you encounter a problem and cannot debug online, can you only republish it by adding a log?
  • I encountered a problem with the data processing of a certain user online, but it also cannot be debugged online, and cannot be reproduced offline!
  • Is there a global view into the health of the system?
  • Is there any way to monitor the real-time running status of the JVM?
  • How to quickly locate application hotspots and generate flame graphs?
  • How to find an instance of a class directly from within the JVM?

image-20221010233314993

Official address: https://arthas.aliyun.com/

Installation and use

start command

java -jar arthas-boot.jar

Because there are Chinese documents, the main learning is to refer to the official documents.

07-Java Mission Control

history

Before Oracle acquired Sun, Oracle's JRockit virtual machine provided a virtual machine diagnostic tool called JRockit Mission Control.

​ After Oracle acquired sun, Oracle owned both Hotspot and JRockit virtual machines. According to Oracle's strategy for Java, in the future development, the excellent features of JRokit will be ported to Hotspot. One of the important improvements is the addition of JRockit support to Sun's JDK.

After Oracle JDK 7u40, the tool Mission Control has been bundled in Oracle JDK.

​ Since Java11, the JFR introduced in this section has been open sourced. But in the previous Java version, JFR belonged to the Commercial Feature and was enabled through the Java virtual machine parameter -XX:+UnlockCommercialFeatures.

Java Mission Control (JMC for short), a powerful tool officially provided by Java, is a tool suite for managing, monitoring, profiling and troubleshooting Java applications. It includes a GUI client and many plug-ins used to collect Java virtual machine performance data, such as JMX Console (which can access MXBeans used to store virtual machine data in the system) and the efficient profiling tool Java Flight Recorder built into the virtual machine ( JFR).

​ Another advantage of JMC is that it uses sampling instead of traditional code implantation technology, which has very little impact on application performance, and it is completely possible to run JMC for stress testing (the only impact may be that there are too many full gcs).

Official address: https://github.com/JDKMissionControl/jmc

start up

image-20221013225635880

overview

Java Mission Control (JMC for short), a powerful tool officially provided by Java. It is a tool for managing, monitoring, profiling and troubleshooting Java applications.

​ It includes a GUI client, and many plug-ins for collecting Java virtual machine performance data, such as JMX Console (which can access MXBeans used to store the running data of each subsystem of the virtual machine), and the built-in efficient profiling tool Java Filght Recorder (JFR).

​ Another advantage of JMC is that it adopts sampling instead of traditional code implantation technology, which has very little impact on application performance. After completion, JMC can be turned on for stress testing (the only impact may be that there are too many full gcs).

Function: Real-time monitoring of the status of JVM runtime

image-20221013230511815

image-20221013230633963

add another item

image-20221013230742188

Java Flight Recorder

event type

When started, JFR will record a series of events that occur during the run. These include events at the Java level. Such as thread events, lock time, and time inside the Java virtual machine, such as creating new objects, garbage collection, and just-in-time compilation time.

Divided according to the timing and duration of occurrence, there are four types of JFR time, and they are as follows:

  1. Instantaneous events (Instant Event), users are concerned about whether they occur or not, such as exceptions and thread start events.
  2. Continuous events (Duration Event), users care about their duration, such as garbage collection events.
  3. A Timed Event is a persistent event whose duration exceeds a specified threshold.
  4. Sample Event is a periodic sampling event.

One of the common examples of sampling events is method sampling (Method Sampling), which counts the stack traces of each thread at regular intervals. If there is a recurring method among these sampled traces, then we can infer that method is the hotspot method.

start up

Method 1: Use -XX:StartFlightRecording= parameter

image-20221015235902800

Method 2: Use the JFR.* subcommand of jcmd

image-20221015235929892

Method 3: JMC's JFR plug-in

image-20221016000049182

Java Flight Recorder Sampling Analysis

1. General Information

image-20221016000454960

2. Memory

image-20221016000513122

3. Code

image-20221016000317007

4. Thread

image-20221016000538235

5、I/O

image-20221016000550787

6. System

image-20221016000616725

7. Events:

image-20221016000423661

08-Other tools

Flame Graphs flame graph

​ In the scenario of pursuing mechanism performance, to understand what the CPU is doing during the running of your program, the flame graph is a very intuitive tool to display the event distribution of the CPU during the entire life cycle of the program.

​ The flame graph should not be unfamiliar to modern programmers. This tool can very intuitively show the CPU consumption bottleneck in the call stack.

Most of the online explanations about java flame graphs come from Brendan Gregg's blog: https://brendangregg.com/flamegraphs.html

image-20221016001244753

The flame graph simply measures the time index through the width of the bar on the x-axis, and the y-axis represents the level of the thread stack.

Tprofiler (no one has maintained it for a long time)

  • case:

Using the tools provided by the JDK itself for JVM tuning can increase the TPS from 2.5 to 20 (a 7-fold increase) and accurately locate system bottlenecks.

System bottlenecks include: there are not too many static objects in the application, a large number of business threads frequently create some temporary objects with a long life cycle, and there are problems in the code.

So, how to accurately locate these performance codes in the massive business codes? Here, Ali open source tool TProfiler is used to locate these performance codes, which successfully solved the performance bottleneck of too frequent GC, and finally increased the TPS by 4 more on the basis of the last optimization, that is, to 100.

  • TProfiler configuration deployment, remote operation, and log reading are not too complicated, and the operation is still very simple. But it can indeed have a sharp and immediate effect, helping us solve the performance bottleneck of too frequent GC.
  • The most important feature of TProfiler is the ability to count the top methods of the JVM within a specified period of time. These top methods are most likely the culprits that cause JVM performance bottlenecks. This is not available in most other JVM tuning tools, including JRockit Mission Control.
  • Download address: https://github.com/alibaba/TProfiler

Btrace

Java runtime tracing tool. It is a secure dynamic tracking tool for the Java platform. Can be used to dynamically track a running Java program.

BTrace dynamically adjusts the target application's classes to inject trace code ("bytecode trace").

YourKit

JProbe

Spring Insight

Guess you like

Origin blog.csdn.net/weixin_43811294/article/details/127342971