标签:rop too 初始 文件名 site tag boolean MIXED sha
目录
问题
jvm的标准参数,在jvm各个版本中基本不变。
使用java
获取所有标准参数
使用java -version
命令可以输出java的版本信息,从第4行可以看到:
JVM的名字(HotSpot)、类型(Server)、build ID(24.79-b02),JVM以混合模式(mixed mode)在运行,这是HotSpot默认的运行模式,意味着JVM在运行时可以动态的把字节码编译为本地代码。关于切换类型(Server Client)以及二者的区别详见参考文档1。
C:\Users\Administrator>java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
非标准化参数,在jvm各个版本中会有一些小变化。
使用java -X
获取所有X参数
-Xint:JVM以解释方式执行所有的字节码,会显著降低运行速度
-Xcomp:JVM在第一次使用时就把所有字节码编译为本地代码
-Xmixed:混合模式(默认),由jvm自己决定是否编译为本地代码,会将字节码中多次被调用的部分便以为本地代码以提高执行效率;被调用很少的方法会在解释模式下执行,减少编译和优化成本
# 默认是mixed mode(混合模式),在java的版本信息中显示
C:\Users\Administrator>java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
# 修改为interpreted mode(解释执行)
C:\Users\Administrator>java -Xint -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, interpreted mode)
# 修改为compiled mode(编译执行)
C:\Users\Administrator>java -Xcomp -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, compiled mode
测试三种JVM工作模式可以使用死循环代码测试运行时间,具体命令如下:
javac HelloWorld.java
java -Xint HelloWorld
java -Xcomp HelloWorld
java -Xmixed HelloWorld
? 非标准化参数,在jvm各个版本中变化较大,主要用于jvm调优和debug,也是最常用的参数
? 使用java -XX:+PrintFlagsFinal -version > flags1.txt
命令获取所有XX参数^③^,大约有700+参数
Boolean 类型
格式:-XX:[+-]
举例:-XX:UseConcMarkSweepGC 启用CMS垃圾收集器
? -XX:+UseG1GC 启用G1垃圾收集器
K-V 类型
格式:-XX:[+-]
举例:-XX:InitialHeapSize=3116367872 初始化堆内存,常用-Xms512m
表示,不要误认为是X参数
-XX:MaxHeapSize=3116367872 最大堆内存,常用-Xmx1024m 表示 |
-XX:ThreadStackSize=1024 线程堆栈大小,常用-Xss128k 表示 |
-XX:MaxGCPauseMills=500 表示GC的最大停顿时间是500ms |
-XX:GCTimeRatio=19 |
jps
:查看java进程。
-m
显示传递给main
方法的参数。
-l
显示应用程序main
类的完整包名称或应用程序的JAR文件的完整路径名。
-v
显示传递给JVM的参数
jinfo
:查看Java进程的修改过的jvm参数
jinfo -flags 2345
查看进程id为2345的jvm参数
jinfo -flag MaxheapSize 2345
查看进程id为2345的jvm参数最大堆内存MaxheapSize
的值
# 进程id21640 输出间隔1000ms 输出次数3
# Loaded加载类的数量 Bytes加载的kB数 Unloaded:卸载的类数 Bytes:卸载的Kbytes数Time:执行类加载和卸载操作所花费的时间
C:\Users\Administrator>jstat -class 21640 1000 3
Loaded Bytes Unloaded Bytes Time
3010 5823.5 52 77.1 3.48
3010 5823.5 52 77.1 3.48
3010 5823.5 52 77.1 3.48
# 输出结果各项指标详见参考文档2
C:\Users\Administrator>jstat -gc 21640
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
18432.0 19456.0 0.0 0.0 77824.0 48459.9 126976.0 10715.1 19456.0 18288.3 2304.0 1968.8 13 0.204 1 0.139 0.342
# 查看JIT编译信息
C:\Users\Administrator>jstat -compiler 21640
Compiled Failed Invalid Time FailedType FailedMethod
3054 1 0 12.35 1 org/apache/tomcat/util/IntrospectionUtils setProperty
/**
* Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit
* exceeded
*/
private static void heapSize2() {
Map<Object,Object> map = new HashMap();
Random r = new Random();
Integer i = 0;
while (true) {
map.put(i++, "aaa");
}
}
/**
* Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
*/
private static void heapSize() {
List<String> names = new ArrayList();
for (;;) {
names.add("bbb");
}
}
使用命令行参数,内存溢出时自动导出(最常用)
-XX+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
另外也可以使用-Xrunhprof:head=site
参数生成java.hprof.txt 文件,不过这样会影响 JVM的运行效率,不建议在生产环境中使用
使用jmap命令手动导出 jmap -dump:format=b,file=heap.hprof 2345
format表示以二进制形式导出,file表示文件名称,2345表示要操作的java进程id
更多jmap命令选项详见参考文档2
首先下载MAT (Memory Analyzer),参考MAT教程^④⑤^,分析dump文件
Shallow Heap表示对象本身所占的内存^④⑤^,Retained Heap表示对象和对象中的引用总共占的内存大小。比如User对象包含name属性,会引用String对象。
排除虚引用,根据GC Roots查看对象引用
CPU负载(load average)^⑦^和使用率过高,很可能的原因就是死循环。
首先可以使用top命令查看占用CPU最高的进程信息,获取进程pid
使用jstack [pid] > myStack.txt
命令打印指定java进程的所有线程堆栈信息
使用Linux命令top -p [pid] -H
监控指定进程中所有线程信息,然后找到CPU占用率高的线程nid(windows中可以process exlporer工具查看指定进程中所有线程信息)
如图可以看到8247(0x2037)
线程的CPU使用率达到了96.7%,此时我们就可以确认是这个线程的问题了
在myStack.txt文件中查看线程id为nid的堆栈信息(myStack.txt线程id是16进制,top -p命令线程id是10进制),就可以找到导致CPU飙升的线程的堆栈信息了,然后分析问题,解决问题。
如图可以看到8247(0x2037)
线程的堆栈信息
另外jstack命令能自动检测到死锁,在myStack.txt末尾会有 “found 1 deadlock”,也会打印死锁线程的相关信息,根据这些信息就可以分析问题,解决问题了。另外,也可以使用JConsole来检测死锁
BTrace可以动态地向目标应用程序的字节码注入追踪代码,用到的技术JavaCompilerAPI,JVMTI,Agent,Instrumentation+ASM
1、接口性能变慢,分析每个方法的耗时情况;
2、当在Map中插入大量数据,分析其扩容情况;
3、分析哪个方法调用了System.gc(),调用栈如何;
4、执行某个方法抛出异常时,分析运行时参数;
下载JVisualVM BTrace插件https://visualvm.github.io/pluginscenters.html
下载BTracehttps://github.com/btraceio/btrace/releases/tag/v1.3.11
jar包
import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
@BTrace
public class PrintArgSimple {
// 在Ch4Controller类的fun1方法的入口处(ENTRY)进行追踪
@OnMethod(clazz = "com.imooc.monitor_tuning.chapter4.Ch4Controller",
method = "fun1", location = @Location(Kind.ENTRY))
public static void anyRead(@ProbeClassName String className, @ProbeMethodName String methodName, AnyType[] args) {
BTraceUtils.printArray(args); //fun1方法的所有参数
BTraceUtils.println(className + ":" + methodName);
}
}
btrace [pid] MyBtrace.java
参考文档:
标签:rop too 初始 文件名 site tag boolean MIXED sha
原文地址:https://www.cnblogs.com/mkwfqd/p/9893546.html