The Definitive Guide to Java Performance - Summary 4

Java Performance Tuning Toolbox

Operating system tools and analysis

CPU run queue

quick summary

  1. When checking application performance, the first thing you should look at is CPU time.
  2. The goal of optimizing code is to increase rather than decrease CPU usage (for a shorter period of time).
  3. Before trying to optimize your application in depth, you should first understand why the CPU usage is low.

disk usage

Monitoring disk usage serves two purposes. The first purpose has to do with the application itself: if the application is doing a lot of disk I/O, then I/O can easily become a bottleneck.

Knowing when disk I/O is the bottleneck is difficult because it depends on the behavior of the application. If the application does not buffer effectively when writing data to the disk, the disk I/O statistics will be very low. However, if the application performs more I/O than the disk can handle, the disk I/O statistics will be very high. Performance in both cases needs to be improved.
Some systems have better basic I/O monitoring than others. This is part of the output of iostat on the Linux system:
insert image description here
the application is writing data to the disk sda. At first glance, the disk stats are not bad. w_await - the time to write each I/O - is quite low (6.08 ms), and the disk usage is only 1.04%. (Acceptable values ​​depend on the physical disk, below 15ms.) But here's a clue that something is wrong: the system spends 37.89% of its time in the kernel. One possibility is that the system is doing other I/O (in other programs). If all this system time comes from the application under test, something inefficient is going on.

Another clue is that the system writes at 24.2 per second: that's a lot when writing only 0.14MB per second. This shows that I/O is already the bottleneck, and the next step is to check how the application is written.

If the disk speed can't keep up with the I/O request, the other side of the problem appears:
insert image description here
Linux has the advantage of telling us immediately that the disk usage rate is 100%. It also tells us that 47.89% of the process's events are in iowait(meaning waiting for disk).

A second reason for monitoring disk usage -- even if the application is not expected to have high I/O -- is to help monitor whether the system is swapping memory. Computers have a fixed amount of physical memory, but they can use much larger virtual memory to run a range of applications. Apps reserve more memory than they actually need, and they often only use a portion of the memory allocated to them. In both cases, the operating system can keep unused memory on disk and page it into physical memory when needed.

In most cases, this type of memory management can work well, especially interactive applications and GUI programs. This type of management is less effective for server-type applications, which require more memory. Because of the Java heap, this management is bad for any Java program.

Systems that are swapping memory -- moving data from main memory to disk or vice versa -- generally have poorer performance. There are other system tools that can report system swapping, for example there are two columns in the vmstat output (si is swap in, so is swap out) that can warn us if the system is swapping. Disk activity indicates that memory swapping may be taking place.
quick summary

  1. Monitoring disk usage is important for all applications. Even for applications that don't write directly to disk, system swapping can still affect their performance.
  2. Applications that write to disk encounter bottlenecks because data is not being written efficiently (throughput is too low), or because too much data is being written (throughput is too high).

network usage

If the application requires the network to run -- such as a Java EE application server -- network traffic must also be monitored. Network usage is similar to disk traffic: an application may be underutilizing the network so the bandwidth is low, or the total amount of data being written to a network interface is more than it can handle.

Standard system tools are not good at monitoring network traffic since they can usually only show the number of datagrams and bytes sent and received by a network interface. While this information is useful, it cannot tell us whether the network is underutilized or overutilized. The basic tool for Unix systems to monitor the network is netstat, which can display the traffic summary of each network interface, including the usage of the network interface:
insert image description here
e1000g1 in the example is a 1000 MB interface, and the usage rate is very low (0.33%). This tool (and others like it) can be used to calculate interface usage. In the above output, the data write rate of the interface is 225.7 Kbps and the read rate is 176.2 Kbps. For a 1000MB network, the utilization rate can be 0.33% after division, and nicstat can also automatically calculate the bandwidth of the interface.

Tools like typeperf or netstat can report data read and written, but to calculate network usage, you must script the bandwidth of the interface yourself. The unit reported by general tools is bytes/second (Bps), but the unit of bandwidth is bits/second (bps). A 1000 megabit network handles 125 megabytes (MB) per second. In this example, read is 0.22 MBps, write is 0.16 MBps, add and divide by 125 to get 0.33% usage. nicstat is more convenient to use.

The network cannot support 100% utilization. For a local Ethernet LAN, sustained network utilization above 40% means the interface is saturated. If the network is packet-switched or uses a different transmission medium, the maximum value of network utilization may be different, so it is best to evaluate the network architecture before determining the appropriate value. This value has nothing to do with Java, but simply uses network parameters and operating system interfaces.

quick summary

  1. For network-based applications, it is important to monitor the network to ensure it is not a bottleneck.
  2. 往网络写数据的应用遇到瓶颈,可能是因为写数据的效率太低(吞吐量太低),也可能是因为写入了太多的数据(吞吐量太高)。
    

Java monitoring tool

To gain insight into the JVM itself, you need to use Java monitoring tools. The JDK comes with the tools listed below:

  • jcnd

Used to print the basic classes, threads and VM information involved in the Java process. It works with scripts and can be executed like this:

%jcmd process_id conmand optional_arguments

jcmd helpAll commands can be listed. jcmd help <command>The syntax for a particular command can be given.

  • jconsole

Provides a graphical view of JVM activity, including thread usage, class usage, and GC activity.

  • jhat

Reads memory heap dumps and helps with analysis. It's an afterthought.

  • jmap

Provides heap dumps and other information about JVM memory usage. Can be adapted for scripting, but the heap dump must be used in a post-mortem analysis tool.

  • jinfo

View the system properties of the JVM, you can dynamically set some system properties. Available for scripts.

  • jstack

Dump the stack information of the Java process. Available for scripts.

  • to stand

Provides information on GC and class loading activity. Available for scripts.

  • jvisualvm

A GUI tool for monitoring the JVM, which can be used to analyze running applications and analyze JVM heap dumps (after the event, jvisualvm can also grab program heap dumps in real time).

These tools are widely used in the following areas:

  • Basic VM information
  • thread information
  • class information
  • Real-time GC analysis
  • Postmortem processing of heap dumps
  • Performance Analysis of JVM

There is not a one-to-one correspondence between tools and fields of application, and many tools can be used in more than one field. So instead of examining each tool individually, we look at the important observable areas of Java and discuss how these tools provide this information. At the same time, we will also discuss other tools (some open source, some commercial) that provide the same basic functionality but have certain advantages over the basic JDK tools.

Basic VM information

JVM tools can provide basic running information of a JVM process: how long it has been running, which JVM flags are used, and JVM system properties, etc.
Running time
This command can view the running time of JVM:

% jcmd process_id VM.uptime

System Properties Individual entries
that can be displayed by the following commands .System.getProperties()

% jcmd process_id VM.systen_properties

or

% jinfo -sysprops process_id

This includes all properties set via the command line -D flag, all properties added dynamically by the application and the JVM's default properties.

JVM version
Get the JVM version in the following way:

% jcmd process_id VM.version

The "VM Summary" page of the JVM command line
jconsole can display the command line used by the program, or display it with jcmd:% jcmd process_id VM.command_line

JVM tuning flags
You can get the JVM tuning flags that are effective for your application in the following ways:

% jcmd process_id VM.flags [-all]

Tuning Flags
The JVM can set a number of tuning flags, the last two jcmd examples above are useful for getting this kind of information. command_line displays flags specified directly on the command line. flags shows flags set by the command line, as well as flags set directly by the JVM (because their values ​​are determined by automatic optimization). When all is added to this command, all flags inside the JVM can be listed.

When diagnosing performance problems, it's common to find out which flags are in play. While the JVM is running, you can do this with jcmd. Adding on the command line -XX:+Printflagsfinalcan be useful if you want to find out what the platform-specific defaults are for a particular JVM.
To find out what flags are set for a particular platform, execute the following command:
% java other_options -XX:+PrintFlagsFinal -version
...a few hundred lines of output, including...

uintx InitialHeapSize : = 4169431040  {product}
intx InlineSmallCode   = 2000                {pd product}

All flags should be included on the command line, as some flags affect others, especially GC-related ones. This command will print a complete list of JVM flags and their values ​​(the result is the same as that printed by jcnd combined with VM.flags -all). Flag data for these commands is displayed in one of the two ways described above. The colon in line 1 of the output indicates that the flag is using a non-default value. This situation may be caused by the following reasons.

  • Flag values ​​are specified directly on the command line.
  • Other flags indirectly change the value of this flag.
  • The JVM automatically optimizes the calculated default value.

Line 2 (without the colon) indicates that the value is the default for this JVM version. The default values ​​for some flags may vary on different platforms, as indicated in the rightmost column of the output. product means that the default settings are the same on all platforms. The default values ​​for the pd product representation flags are platform-independent.

Another tool for viewing such information about a running application is called jinfo. The nice thing about jinfo is that it allows a program to change the value of a flag while executing.
Here's how to get the values ​​of all flags in a process:
% jinfo -flags process_id

When jinfo has -flags, it can provide information about all flags, otherwise it only prints the flags specified on the command line. Neither
data is as readable as -XX:+Printflagsfinal, but jinfo has other noteworthy features.

jinfo can check the value of individual flags:

% jinfo -flag PrintGCDetails process_id
-XX:+PrintGCDetails

Although jinfo itself will not indicate whether it is manageable, the manageable (as identified in the Printflagsfinal output) flag can be turned on or off by jinfo:

% jinfo -flag -PrintGCDetails process_id # turns off PrintGCDetails
% jinfo -flag PrintGCDetails process_id
-XX:-PrintGCDetails

Beware that jinfo can change the value of any flag, but that doesn't mean the JVM will respond to the change. For example, most of the flags that affect the behavior of the GC algorithm are used at startup to determine how the garbage collector behaves. Changing the flag value later via jinfo does not cause the JVM to change its behavior. It continues with the original algorithm. So this technique will only work for those flags marked as manageable in the Printflagsfinal output.

quick summary

  1. jcmd can be used to find basic information about the JVM running an application - including the values ​​of all tuning flags.
  2. 2. Add l on the command line -XX:+Printflagsfinato output the default value of the flag. This is useful when looking at the default values ​​determined by platform-specific auto-optimization.
    3. info is useful when inspecting (and in some cases changing) individual flags.

Guess you like

Origin blog.csdn.net/weixin_42583701/article/details/130998187