1. Parameter type of JVM
Tools documentation https://docs.oracle.com/javase/8/docs/technotes/tools/unix/
1. Standard parameters
2. - X parameters
Nonstandard parameter: it may be different in different versions of JVM
java defaults to mixed mode
For example, change java mode to interpretation mode: java -Xint -version
3. XX parameter
boolean type
That is, if + plus sign is start, if - minus sign is disable
Non Boolean type
-Xmx -Xms
That is, set the maximum and minimum memory of the JVM
For example, xss sets the stack with a XX type parameter
View JVM runtime parameters
printFlagsInitial initial
printFlagsFinal is the final value
printFlagsFinal is the final value
jps
jps commands for viewing java processes
That is, jps-L plus a small L will know the complete class name of the corresponding process
All commands of jps use documents
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html
jinfo
jinfo can view the running
Non default VM flags shows all manually assigned attributes
jinfo example
jstat viewing JVM statistics
Such as class loading, garbage collection, JIT compilation
Command format
Class loading
1000 10 is output 10 times per 1000 milliseconds, that is, 10 times per second.
garbage collection
-gc output results
Memory structure of jvm
The non heap area is the local memory of the operating system, which is independent of the heap area
CCS enables short pointers, such as pointing to its own objects and pointing to its own Class
CodeCache is the code information of jit, that is, java code is converted to native code. If you don't open it, it's empty
JIT compilation
Export memory image file
Export memory image to solve the problem of memory overflow
Memory overflow auto export
When memory overflow occurs, the jvm automatically exports
Export manually using jmap command
For example, jmap -dump:format=b,file=heap.hprof 86224
You can dump the corresponding process into a file
pid can be viewed through jsp-l
Using MAT to analyze memory overflow based on memory image file
MAT Download
http://www.eclipse.org/mat/downloads.php
Using mat to import the previous hprof file for careful analysis can find out the memory overflow
jstack and thread state
jstack can view the running thread status,
For example, if the CPU is very high, it may be a dead cycle, and then check which thread is causing the problem
Such as execution
Jstack 15764 > 15764.txt gives the thread information to the exported file, and then it can be analyzed
Thread state and transition
java thread status https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr034.html java thread state transformation: https://mp.weixin.qq.com/s/GsxeFM7QWuR--Kbpb7At2w
That is, when there is a dead cycle, the CPU will be very high.
1. With the top command, you can see the process with high CPU, that is, the corresponding pid
2. Then use the PID seen in the first step to execute top-p pid-h
3. Convert the CPU pid to decimal pid using printf "% X"
4. Execute "Jack pid > XX. TXT" to export the pid information of high CPU to a file
5. Find the corresponding thread in xx.txt with the decimal pid of step 3
With the stack information of the thread, you can check whether there is a dead cycle in the execution of that part of the code
In the same way, deadlock is the same as solving the dead cycle, using the "Jack PID > xx.txt"
Just look at the content (you can see whether there is deadlock information at the end of the file)
Visual monitoring based on JVisualVM
JVisualVM is a tool that comes with jdk. You can find it under jdk/bin
The function is the same as that of Jack and mat. This is a graphical interface, which can be used without any command
Install plug-ins such as Visual GC plug-ins
Reference https://blog.csdn.net/ljllxk001/article/details/97016520
https://blog.csdn.net/WilliamHaoW/article/details/86243807
Visaul GC, you can refer to the detailed GC information and memory usage, very detailed. However, remote access does not support JMX mode. jstatd mode must be used
Visaul MBeans, jmx management interface, can manage all MBeans in the application. If spring is used, the bean s can be exposed through jmx integration of spring, and the configuration of various applications can be modified in real time.
Profile, cpu and memory performance analysis can filter the classes that do not need to be monitored according to the package name
BTrace, you can debug the code without downtime. You can right-click trace application G on visual VM Open BTrace window (local jvm only)
--------
Copyright notice: This is the original article of CSDN blogger "haoclassmate", following CC 4.0 BY-SA copyright agreement. Please attach the original source link and this notice for reprint.
Original link: https://blog.csdn.net/william haow/article/details/86243807
Monitoring remote java processes such as Tomcat
hostname is the IP address of the remote host. Please configure the port and IP address
Or reference https://jingyan.baidu.com/article/ff411625b5761e12e5823745.html
Solution: 1. Find the catalina.sh file on the server, and add the following content on the line of the file: CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.1.2 -Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" Then start the tomcat process
Note that hostname is the IP address of the current tomcat machine
Monitoring remote common java processes
Namely
[root@localhost soft]# java -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.230.250 -Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar monitor_tuning-0.0.1-SNAPSHOT.war //perhaps java -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=9999 -Djava.rmi.server.hostname=192.168.132.250 -jar monitor_tuning-0.0.1-SNAPSHOT.jar
In the above jar mode, I can't succeed in remote monitoring. The project is started, but the remote connection fails. We need to see if the firewall is on. In particular, is the IP address of the corresponding server?
Reference material
jvisualVM: https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/index.html https://visualvm.github.io/documentation.html How to add plug-ins to jvisulaVM https://visualvm.github.io/index.html
Monitoring and debugging based on Btrace
btrace Download https://github.com/btraceio/btrace https://github.com/btraceio/btrace/releases/tag/v1.3.11
Function
There are two ways to run the above
Detailed explanation
Interception opportunity
That's when to intercept the return value
Interception anomaly
That is, it can catch even the exception that is try caught
@OnMethod( clazz="java.lang.Throwable", method="<init>", location=@Location(Kind.RETURN) ) public static void onthrowreturn() { if (currentException != null) { BTraceUtils.Threads.jstack(currentException); BTraceUtils.println("====================="); currentException = null; } }
Intercept line number
Intercept replication parameters, environment variables
Matters needing attention
That is to say, if the JVM does not restart, the modified bytecode will still execute. Therefore, we should pay attention to the operation that consumes too much system resources
arthas, a substitute of btace
It is said that Ali's arthas are more powerful, and btace will be used less in the future
tomcat performance monitoring and tuning
tomcat remote debug ging
jdwp protocol: https://www.ibm.com/developerworks/cn/java/j-lo-jpda3/
1. Add jpda at the end of startup.sh
2. Modify the port in catalina.sh, which is 8000 by default
After that, you can configure idea for remote debug ging
idea can be referred to https://blog.csdn.net/helllochun/article/details/40890277
Similarly, if the configuration is in the form of spring boot jar:
java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n -jar ****.jar
In this way, it is more convenient to debug in the development stage
Tomcat manager monitoring
It is not enabled by default in higher versions
File
{tomcat}/webapps/docs/manager-howto.html
<role rolename="tomcat"/> <role rolename="manager-status"/> <role rolename="manager-gui"/> <user username="tomcat" password="123456" roles="tomcat,manager-status,manager-gui"/>
Create manager.xml manually in apache-tomcat-8.5.43\conf\Catalina\localhost
<?xml version="1.0" encoding="UTF-8"?> <Context privileged="true" antiResourceLocking="false" docBase="${catalina.home}/webapps/manager"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1" /> </Context>
Start tomcat
Visit http://127.0.0.1:8080/manager/html
You can see the memory information of the JVM, the maximum number of threads supported by the current tomcat, and the current number of threads
Number of busy threads. Very meaningful.
PSI probe monitoring
tomcat's own manager monitoring is a relatively simple monitoring tool, which is very powerful.
Or through https://repo1.maven.org/maven2/com/github/psi-probe/psi-probe-web/ Download war package
As with tomcat manager configuration, both Tomcat users.xml and manager.xml need to be configured,
Configuration mode is the same as tomcat manager configuration
Including the number of requests, request processing time, request response bytes
tomcat optimization
Memory optimization, thread optimization, configuration optimization
Thread optimization
The above is the view directory of tomcat thread's documents
Max connections the maximum number of connection threads, NIO default connection number is 10000
acceptCount means that when the current number of connections exceeds maxConnections, these connections will be put into a queue. This value can control the size of the queue. The default value is 100. If the value is large, it doesn't make sense.
maxThreads is the number of concurrent requests that can be processed at the same time point. The default is 200
minSpareThreads cannot be set too small. If a lot of requests come suddenly, they will come for urgent processing
Configuration optimization
autoDeploy will affect certain performance, because a thread needs to be opened to check whether there is a new application
Default is false
Do not query DNS, query DNS will affect performance
reloadable =true, that is, when the application has changed files, it will be automatically reloaded, which is usually enabled during development
Nginx performance monitoring and tuning
install
nginx official website documents http://nginx.org/en/docs/
NGX? HTTP? Stub? Status monitoring connection information
Add this module when NGINX compilation is required
By default, the
ngx_http_stub_status: http://nginx.org/en/docs/http/ngx_http_stub_status_module.html
You can view the current concurrency through this
ngxtop monitoring request information
ngxtop: https://github.com/lebinh/ngxtop
Use example
Graphical monitoring of nginx RRD
nginx-rdd http://www.linuxde.net/2012/04/9537.html
You need to configure NGX HTTP stub status to monitor connection information
Then configure php dependency
nginx optimization
Threads and concurrency these configurations are limited by the operating system
Configure long connection of backend server
Keep alive? Timeout the configured connection time of long connection
However, by default, there is no connection time limit for the long connection between nginx and the back-end server
Configuration compression
Operating system optimization
Mainly the parameter optimization of TCP/IP
Generally speaking, TW recycle does not need to be configured. It is OK by default
Configuration of file open limit per process
Other optimization
If the application needs to respond quickly, then TCP ﹣ nodelay can be set to on
GC tuning of JVM layer
Memory structure of JVM
Runtime data area
The runtime data area is different from the memory structure.
The runtime data area is a specification, and the memory structure of the JVM is an implementation of it.
Here is the data area of the JVM:
Reference: https://www.imooc.com/article/47149
Program counter PC Register
Virtual machine stack JVM Stacks
Heap Heap
Method Area
In JDK8, it is MetaSpace. In JDK6,7, it is PerSpace
Constant pool run time constant pool
Constant pools are part of the method area
Native Method Stacks
Memory structure diagram of JVM (need to remember)
The heap is divided into Young area and Old area
Young: s (S0 and S1), Eden
S is divided into two parts of the same size: S0 and S1 (also called From and To). At the same time, only one part has data and the other is empty
Non heap area: CCS compresses the Class space (i.e. points to the Class file with a short pointer), CodeCache is the compiled code and the Navicat code of the JVM. If JIT compilation is not enabled and JNI local methods are not referenced, then this does not exist
JIT: Just In Time Compiler. Reference https://www.cnblogs.com/linghu-java/p/8589843.html
CCS: only when the short pointer is enabled can it exist. Every object allocated in the heap has a pointer to its own Class. If performance reasons are taken into account, the pointer is referred to as 32-bit by using the short pointer. If the short pointer is used, the referenced Class file will be stored in CCS.
CCS: Compressed class space utilization as a percentage
Reference https://www.cnblogs.com/milton/p/6134251.html
Non reactor area
Turn on the short pointer, which is turned on by default
Prohibit
View gcc of a java process
jstat -gc 89192
It can be seen that there is no CCSC and CCSU, and there is no disable
MC is Metaspace. If the short pointer is disabled, the long pointer will be longer, and you can see that it is larger than the Metaspace that used the short pointer before.
-Xint implementation application observation
Then look at gc
jstat -gc 89192
It will be found that the size of MC is smaller than that of the previous default mode, i.e. mixed mode. Because the code is compiled using the - Xint interpretation mode, the JAVA code will not be generated into the local code, which is put into CodeCache.
Common parameters of jvm
-20: NewSize is the size of the Cenozoic
NewRatio is the ratio of the size of new area (Young area) to old area
SurvivorRatio is the ratio of Eden area to S area (the ratio of two parts in Young area)
MetaspaceSize is the size of the Metaspace non heap area
CompressedClassSpaceSize sets the size of the compressed class space, which is the size of CCS.
If + usedecompressedclasspoints is enabled, the default CCS size is 1g
Initialcodecache size: initialize CodeCache size
Reservedcodachesize: the maximum size of CodeCache
Common garbage collection algorithms
Mark removal
copy
young area is the algorithm used
Mark finishing
Garbage collection by belt
Object assignment
Pretensionesizethreshold specifies how large an object can be directly aged, that is, old area
MaxTenuringThreshold can be used to set how long an object can live directly into the elderly generation
PrintTenuringDistribution refers to the age distribution of printing objects when yong gc occurs
TargetSurvivorRatio sets the ratio of objects surviving in S area after garbage collection, that is, according to certain rules, objects can be directly promoted to old area
Reference https://www.jianshu.com/p/f91fde4628a5
garbage collector
That is, the parallel collector is the throughput first collector.
Concurrent collector is the collector with pause time priority
MaxGCPauseMillis is the maximum pause time
For example, if you set GCTimeRatio =19, the garbage collection time is 1 / (1 + 19) = 1 / 20
The ideal situation is the maximum throughput with the minimum pause time. But the reality is that the pause time and throughput cannot be satisfied at the same time. When adjusting, adjust according to the actual situation
Serial Collector
parallel collector
concurrent collector
There are two options for parallel collectors: G1 and CMS
G1 is recommended for high performance
Garbage collector collocation
Select garbage collector
GC Tuning Guide: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html How to choose a garbage collector https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html
Details of parallel garbage collector
Parallel collectors: adaptive configuration
That is, configure some parameters and let the garbage collector adjust the heap size to meet the following conditions
The above settings give priority to throughput requirements, followed by pause time requirements
This is not the best way. If you are not familiar with tuning, you can set it like this
Dynamic memory adjustment
When adaptive, dynamic memory adjustment is needed to meet the setting requirements
YoungGenerationSizeIncrement is the adjusted size of yong area every time it is dynamically adjusted. The default value is 20%
old area: it is the following parameter control, which is also 20% by default
If it is too large, it will be reduced. It is the following parameter control. The default is 4%
Use the above parameters to dynamically adjust the memory size to meet the setting requirements
Concurrent CMS
Garbage collection process
STW: the execution of the application will be stopped
shortcoming
CMS related parameters
There was Perm before JDK7
CMSInitiatingOccupancyFraction by default 92%, that is, when the old area size reaches 92%, FullGC will be triggered
iCMS incremental CMS
Abandoned in JDK8
G1 garbage collector
The above is the memory mark of G1 collector, in Region.
In G1, there are old areas and yong areas. The bottom is the top
H is the storage mark of large objects
G1 concept
YoungGC process
MixedGC
global concurrent marking
mixedGC opportunity
Related parameters
That is, the number of region s that can be recycled by a GC
ParallelGCThreads is the number of parallel GC threads (i.e. when the application needs to be stopped), SWT is the number of GC threads that need to be stopped
Not with the application
ConcGCThreads is the number of concurrent threads (executed with the application = 1 / 4 * ParallelGCThreads)
Best practices
That is, 90% of the time is for application execution, and 10% is for garbage collection
Need to switch to G1
Details of GC log format
Print log related parameters
Printheapatgc: print the usage of the whole heap during GC
PrintTenuringDistribution: print the age distribution information of objects in yong area
ParallelGC log format
Allocation Failure: cause of GC
GC without Full is young gc
- >: before gc - > after gc
Metadata GC Threshold: caused by insufficient Metaspace space
young area GC Before garbage collection yong Size Size after garbage collection yong Total area size gc Total size of front heap [PSYoungGen] : 31744k -> 5113k (36864k) ] 31744k -> gc Total size of the post heap total size of the heap Recycling time 10233k (121856) , 0.0023 sec
cms log format
G1 - YoungGC log format
CMS log format https://blogs.oracle.com/poonam/understanding-cms-gc-logs G1 log format https://blogs.oracle.com/poonam/understanding-g1-gc-logs
Visual GC analysis tool
GC log analysis tool http://gceasy.io/ GCViewer https://github.com/chewiebug/GCViewer ZGC: http://openjdk.java.net/jeps/333
gceasy is an online tool, which can be analyzed by uploading gc logs
GCViewer is a local tool: download address https://github.com/chewiebug/GCViewer/wiki/Changelog
Parallelgc tuning
jinfo can dynamically set the value of parameters
Tuning principle
When tuning, one parameter at a time to tune, do not set all at once to debug.
If you have a large number of ygcs, you can try to increase the parameter value of YoungGenerationSizeIncrement, submit the throughput and reduce the pause time
Tuning parameters reference website
https://opts.console.perfma.com/
Or refer to the tuning guide on the java official website
https://docs.oracle.com/javase/8/
JVM bytecode and Java code layer tuning
java virtual machine specification https://docs.oracle.com/javase/specs/jvms/se8/html/index.html java language specification https://docs.oracle.com/javase/specs/jls/se8/html/index.html javap: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javap.html Field descriptor https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2 Method Descriptor https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3 Bytecode instruction: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html Constant pool: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4 Local variable table: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.1 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.13 Operand stack: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.2 Code attribute: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3 LineNumberTable: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.12 constant variable: https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4 Constant expression https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28
javap
For example, check the bytecode of a class file
jvm bytecode instruction
Stack based architecture
public class Test1 { public static void main(String args) { int a=2; int b=3; int c = a + b; System.out.println(c); } /*** public static void main(java.lang.String); descriptor: (Ljava/lang/String;)V # Descriptor: V represents no return value, with a string type parameter flags: ACC_PUBLIC, ACC_STATIC # Method description public, static Code: # Depth of operand stack 2 # The maximum length (slot) of the local variable table is 2 for 64 bit and 1 for others. The index starts from 0. If it is a non static method, index 0 represents this, followed by the input parameter, followed by the local variable # 1 this parameter for instance method stack=2, locals=4, args_size=1 0: iconst_2 #Constant 2 stack pressing 1: istore_1 #Save the stack to local variable 1 2: iconst_3 #Constant 3 stack pressing 3: istore_2 #Save the stack to local variable 2 4: iload_1 #Local variable 1 stack 5: iload_2 #Local variable 2 stack 6: iadd # Add the two elements at the top of the stack and press the calculation result 7: istore_3 # Save the stack to local variable 3 8: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 11: iload_3 12: invokevirtual #22 // Call the instance Method java/io/PrintStream.println:(I)V 15: return LineNumberTable: line 5: 0 # The fifth line of the source code corresponds to the above 0 line 6: 2 # 2 Represents the instruction with number 2 above line 7: 4 line 8: 8 line 9: 15 LocalVariableTable: Start Length Slot Name Signature 0 16 0 args Ljava/lang/String; 2 14 1 a I 4 12 2 b I 8 8 3 c I **/ }
i + + and + + i
package com.imooc.monitor_tuning.chapter8; public class SelfAdd { public static void main(String[] args) { f3(); f4(); } /** public static void f1(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=0 0: iconst_0 1: istore_0 2: goto 15 5: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream; 8: iload_0 9: invokevirtual #25 // Method java/io/PrintStream.println:(I)V 12: iinc 0, 1 15: iload_0 16: bipush 10 18: if_icmplt 5 21: return * */ public static void f1() { for(int i=0;i<10;i++) { System.out.println(i); } } /** public static void f2(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=0 0: iconst_0 1: istore_0 2: goto 15 5: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream; 8: iload_0 9: invokevirtual #25 // Method java/io/PrintStream.println:(I)V 12: iinc 0, 1 15: iload_0 16: bipush 10 18: if_icmplt 5 21: return * */ public static void f2() { for(int i=0;i<10;++i) { System.out.println(i); } } /** public static void f3(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=0 0: iconst_0 1: istore_0 2: iload_0 3: iinc 0, 1 6: istore_1 7: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream; 10: iload_1 11: invokevirtual #25 // Method java/io/PrintStream.println:(I)V 14: return * */ public static void f3() { int i=0; int j = i++; System.out.println(j); } /** public static void f4(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=0 0: iconst_0 1: istore_0 2: iinc 0, 1 5: iload_0 6: istore_1 7: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream; 10: iload_1 11: invokevirtual #25 // Method java/io/PrintStream.println:(I)V 14: return * */ public static void f4() { int i=0; int j = ++i; System.out.println(j); } }
It doesn't make any difference
String splicing+
package com.imooc.monitor_tuning.chapter8; public class StringAdd { public static void main(String[] args) { } /** public static void f1(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=2, args_size=0 0: ldc #19 // String 2: astore_0 3: iconst_0 4: istore_1 5: goto 31 8: new #21 // class java/lang/StringBuilder 11: dup 12: aload_0 13: invokestatic #23 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 16: invokespecial #29 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V new StringBuilder(src) 19: ldc #32 // String A 21: invokevirtual #34 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #38 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore_0 28: iinc 1, 1 31: iload_1 32: bipush 10 34: if_icmplt 8 37: getstatic #42 // Field java/lang/System.out:Ljava/io/PrintStream; 40: aload_0 41: invokevirtual #48 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 44: return * */ public static void f1() { String src = ""; for(int i=0;i<10;i++) { //Every cycle will be a new StringBuilder src = src + "A"; } System.out.println(src); } public static void f2() { //Just one StringBuilder StringBuilder src = new StringBuilder(); for(int i=0;i<10;i++) { src.append("A"); } System.out.println(src); } public static void f3() { //jvm optimization is directly a SCR = AAAAA AAAA String src = "A"+"A"+"A"+"A"+"A"+"A"+"A"+"A"+"A"+"A"; System.out.println(src); } public static void f4() { //In this case, there is only one StringBuilder int a=1; int b=2; if (b==2){ b=3; } String src = "A"+"A"+"A"+"A"+"A"+"A"+"A"+"A"+"A"+"A"+a+b; System.out.println(src); } }
Corresponding bytecode
Classfile /F:/oumin/learn/project/jvm-coding-241/monitor_tuning/target/classes/com/imooc/monitor_tuning/chapter8/StringAdd.class Last modified 2019-12-26; size 1501 bytes MD5 checksum a6f4368568818f8f3796aed1e02f4c4b Compiled from "StringAdd.java" public class com.imooc.monitor_tuning.chapter8.StringAdd minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #14.#43 // java/lang/Object."<init>":()V #2 = String #44 // #3 = Class #45 // java/lang/StringBuilder #4 = Methodref #3.#43 // java/lang/StringBuilder."<init>":()V #5 = Methodref #3.#46 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #6 = String #47 // A #7 = Methodref #3.#48 // java/lang/StringBuilder.toString:()Ljava/lang/String; #8 = Fieldref #49.#50 // java/lang/System.out:Ljava/io/PrintStream; #9 = Methodref #51.#52 // java/io/PrintStream.println:(Ljava/lang/String;)V #10 = Methodref #51.#53 // java/io/PrintStream.println:(Ljava/lang/Object;)V #11 = String #54 // AAAAAAAAAA #12 = Methodref #3.#55 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; #13 = Class #56 // com/imooc/monitor_tuning/chapter8/StringAdd #14 = Class #57 // java/lang/Object #15 = Utf8 <init> #16 = Utf8 ()V #17 = Utf8 Code #18 = Utf8 LineNumberTable #19 = Utf8 LocalVariableTable #20 = Utf8 this #21 = Utf8 Lcom/imooc/monitor_tuning/chapter8/StringAdd; #22 = Utf8 main #23 = Utf8 ([Ljava/lang/String;)V #24 = Utf8 args #25 = Utf8 [Ljava/lang/String; #26 = Utf8 MethodParameters #27 = Utf8 f1 #28 = Utf8 i #29 = Utf8 I #30 = Utf8 src #31 = Utf8 Ljava/lang/String; #32 = Utf8 StackMapTable #33 = Class #58 // java/lang/String #34 = Utf8 f2 #35 = Utf8 Ljava/lang/StringBuilder; #36 = Class #45 // java/lang/StringBuilder #37 = Utf8 f3 #38 = Utf8 f4 #39 = Utf8 a #40 = Utf8 b #41 = Utf8 SourceFile #42 = Utf8 StringAdd.java #43 = NameAndType #15:#16 // "<init>":()V #44 = Utf8 #45 = Utf8 java/lang/StringBuilder #46 = NameAndType #59:#60 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #47 = Utf8 A #48 = NameAndType #61:#62 // toString:()Ljava/lang/String; #49 = Class #63 // java/lang/System #50 = NameAndType #64:#65 // out:Ljava/io/PrintStream; #51 = Class #66 // java/io/PrintStream #52 = NameAndType #67:#68 // println:(Ljava/lang/String;)V #53 = NameAndType #67:#69 // println:(Ljava/lang/Object;)V #54 = Utf8 AAAAAAAAAA #55 = NameAndType #59:#70 // append:(I)Ljava/lang/StringBuilder; #56 = Utf8 com/imooc/monitor_tuning/chapter8/StringAdd #57 = Utf8 java/lang/Object #58 = Utf8 java/lang/String #59 = Utf8 append #60 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #61 = Utf8 toString #62 = Utf8 ()Ljava/lang/String; #63 = Utf8 java/lang/System #64 = Utf8 out #65 = Utf8 Ljava/io/PrintStream; #66 = Utf8 java/io/PrintStream #67 = Utf8 println #68 = Utf8 (Ljava/lang/String;)V #69 = Utf8 (Ljava/lang/Object;)V #70 = Utf8 (I)Ljava/lang/StringBuilder; { public com.imooc.monitor_tuning.chapter8.StringAdd(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/imooc/monitor_tuning/chapter8/StringAdd; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=0, locals=1, args_size=1 0: return LineNumberTable: line 5: 0 LocalVariableTable: Start Length Slot Name Signature 0 1 0 args [Ljava/lang/String; MethodParameters: Name Flags args public static void f1(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=0 0: ldc #2 // String 2: astore_0 3: iconst_0 4: istore_1 5: iload_1 6: bipush 10 8: if_icmpge 37 11: new #3 // class java/lang/StringBuilder 14: dup 15: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 18: aload_0 19: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: ldc #6 // String A 24: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 27: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 30: astore_0 31: iinc 1, 1 34: goto 5 37: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 40: aload_0 41: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 44: return LineNumberTable: line 37: 0 line 38: 3 line 40: 11 line 38: 31 line 42: 37 line 43: 44 LocalVariableTable: Start Length Slot Name Signature 5 32 1 i I 3 42 0 src Ljava/lang/String; StackMapTable: number_of_entries = 2 frame_type = 253 /* append */ offset_delta = 5 locals = [ class java/lang/String, int ] frame_type = 250 /* chop */ offset_delta = 31 public static void f2(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=0 0: new #3 // class java/lang/StringBuilder 3: dup 4: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 7: astore_0 8: iconst_0 9: istore_1 10: iload_1 11: bipush 10 13: if_icmpge 29 16: aload_0 17: ldc #6 // String A 19: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: pop 23: iinc 1, 1 26: goto 10 29: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 32: aload_0 33: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 36: return LineNumberTable: line 46: 0 line 47: 8 line 48: 16 line 47: 23 line 50: 29 line 51: 36 LocalVariableTable: Start Length Slot Name Signature 10 19 1 i I 8 29 0 src Ljava/lang/StringBuilder; StackMapTable: number_of_entries = 2 frame_type = 253 /* append */ offset_delta = 10 locals = [ class java/lang/StringBuilder, int ] frame_type = 250 /* chop */ offset_delta = 18 public static void f3(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=0 0: ldc #11 // String AAAAAAAAAA 2: astore_0 3: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 6: aload_0 7: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 10: return LineNumberTable: line 55: 0 line 56: 3 line 57: 10 LocalVariableTable: Start Length Slot Name Signature 3 8 0 src Ljava/lang/String; public static void f4(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=0 0: iconst_1 1: istore_0 2: iconst_2 3: istore_1 4: iload_1 5: iconst_2 6: if_icmpne 11 9: iconst_3 10: istore_1 11: new #3 // class java/lang/StringBuilder 14: dup 15: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 18: ldc #11 // String AAAAAAAAAA 20: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 23: iload_0 24: invokevirtual #12 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 27: iload_1 28: invokevirtual #12 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 31: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 34: astore_2 35: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 38: aload_2 39: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 42: return LineNumberTable: line 60: 0 line 61: 2 line 62: 4 line 63: 9 line 65: 11 line 66: 35 line 67: 42 LocalVariableTable: Start Length Slot Name Signature 2 41 0 a I 4 39 1 b I 35 8 2 src Ljava/lang/String; StackMapTable: number_of_entries = 1 frame_type = 253 /* append */ offset_delta = 11 locals = [ int, int ] } SourceFile: "StringAdd.java"
That is to say, starting from jdk7, string splicing in some cases will indeed be optimized to have only one StringBuilder object, but in for and other circular cases, each string splicing will produce a new StringBuilder object.
So in the future, we should try to use Stringbuilder instead of string splicing
try-finally
/** public static java.lang.String f1(); descriptor: ()Ljava/lang/String; flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=3, args_size=0 0: ldc #34 // String hello 2: astore_0 3: aload_0 4: astore_2 5: ldc #36 // String imooc 7: astore_0 8: aload_2 9: areturn 10: astore_1 // Stored abnormal information, if any 11: ldc #36 // String imooc 13: astore_0 14: aload_1 15: athrow * */ public static String f1() { String str = "hello"; try{ return str; } finally{ str = "imooc"; } }
String Constant Variable
Constant variable of string
In the higher version of JDK, for example, the method in jdk8 does not need to specify final self-cultivation, and the lower version is only useful
/** 0: ldc #8 // String hello 2: astore_0 3: ldc #46 // String helloworld 5: astore_1 6: ldc #48 // String hellohelloworld 8: astore_2 9: getstatic #31 // Field java/lang/System.out:Ljava/io/PrintStream; 12: aload_2 13: invokevirtual #37 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 16: return * */ public static void f1() { final String x="hello"; final String y=x+"world"; //Compile time substitution occurs String z=x+y; System.out.println(z); } /** 0: ldc #19 // String hello 2: astore_1 3: ldc #21 // String helloworld 5: astore_2 6: new #42 // class java/lang/StringBuilder 9: dup 10: ldc #19 // String hello 12: invokespecial #44 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 15: aload_2 16: invokevirtual #46 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #50 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_3 23: getstatic #25 // Field java/lang/System.out:Ljava/io/PrintStream; 26: aload_3 27: invokevirtual #31 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 30: return * */ public void f2(){ final String x="hello"; String y=x+"world"; String z=x+y; System.out.println(z); }
After the above code is executed, only Hello = ("hello" + LO) results in false
Because lo is a variable, it is actually a string generated by new StringBuilder,
hello is optimized during compilation. It takes the objects in the string constant pool.
So this is false, and the rest are true
intern()
String.intern https://blog.csdn.net/goldenfish1919/article/details/80410349
That is to say, when the inern method is called, if the constant pool has the string, the string will be taken, otherwise a string will be generated and put into the constant pool
String remove weights https://blog.csdn.net/goldenfish1919/article/details/20233263
Common code optimization methods
If we can know the maximum capacity, we can initialize it and improve the efficiency of program execution. Avoid expansion.
For example, the length of the set here will be repeatedly calculated
The System.arraycopy bottom layer calls the native code to execute.
Because the jvm compiler actually uses the Integer method instead of the direct int
TIP: you need to make a direct trade-off between development efficiency and performance. In most cases, there will be no performance problem. Try not to reduce the development efficiency for the ultimate performance.
Reference tool and resource address
Chapter 1 //nothing //The second chapter jdk8 Toolset https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.html Troubleshooting https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/ jps https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html jinfo https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html jstat https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html jmap: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html mat: http://www.eclipse.org/mat/downloads.php jstack: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html java State of thread https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr034.html java Thread state conversion: https://mp.weixin.qq.com/s/GsxeFM7QWuR--Kbpb7At2w //High CPU load due to dead cycle https://blog.csdn.net/goldenfish1919/article/details/8755378 //Regular expression causes a dead loop: https://blog.csdn.net/goldenfish1919/article/details/49123787 //The third chapter jvisualVM: https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/index.html https://visualvm.github.io/documentation.html jvisulaVM How to add a plug-in https://visualvm.github.io/index.html //The fourth chapter btrace download https://github.com/btraceio/btrace https://github.com/btraceio/btrace/releases/tag/v1.3.11 //The fifth chapter jdwp Agreement: https://www.ibm.com/developerworks/cn/java/j-lo-jpda3/ tomcat-manager: {tomcat}/webapps/docs/manager-howto.html psi-probe: https://github.com/psi-probe/psi-probe tomcat Optimize relevant parameters: ${tomcat}/webapps/docs/config/http.html ${tomcat}/webapps/docs/config/host.html ${tomcat}/webapps/docs/config/context.html ${tomcat}/webapps/docs/connectors.html apr Connector: http://apr.apache.org/ //The sixth chapter nginx Official website documents http://nginx.org/en/docs/ nginx Installation: http://nginx.org/en/linux_packages.html ngx_http_stub_status: http://nginx.org/en/docs/http/ngx_http_stub_status_module.html ngxtop: https://github.com/lebinh/ngxtop nginx-rdd http://www.linuxde.net/2012/04/9537.html //The seventh chapter jvm Runtime data area for https://docs.oracle.com/javase/specs/jvms/se8/html/index.html Metaspace http://ifeve.com/jvm-troubleshooting-guide-4/ //Compress class space https://blog.csdn.net/jijijijwwi111/article/details/51564271 CodeCache https://blog.csdn.net/yandaonan/article/details/50844806 http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/ GC Tuning Guide: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html //How to choose a garbage collector https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html G1 Best practices https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations G1 GC Some key technologies of https://zhuanlan.zhihu.com/p/22591838 CMS Log format https://blogs.oracle.com/poonam/understanding-cms-gc-logs G1 Log format https://blogs.oracle.com/poonam/understanding-g1-gc-logs GC Log analysis tool http://gceasy.io/ GCViewer https://github.com/chewiebug/GCViewer ZGC: http://openjdk.java.net/jeps/333 //The eighth chapter java Virtual machine specification https://docs.oracle.com/javase/specs/jvms/se8/html/index.html java language norm https://docs.oracle.com/javase/specs/jls/se8/html/index.html javap: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javap.html //Field descriptor https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2 //Method Descriptor https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3 //Bytecode instruction: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html //Constant pool: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4 //Local variable table: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.1 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.13 //Operand stack: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.2 Code Properties: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3 LineNumberTable: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.12 constant variable: https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4 //Constant expression https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28 String.intern https://blog.csdn.net/goldenfish1919/article/details/80410349 String Duplicate removal https://blog.csdn.net/goldenfish1919/article/details/20233263