JVM总结
一、手动编译JAVA
wget https://download.java.net/java/ga/jdk11/openjdk-11_osx-x64_bin.tar.gz open-jdk:https://github.com/unofficial-openjdk/openjdk 教程:https://www.jianshu.com/p/b8177780c939
二、原理
- new对象时全过程
- 对象访问
Object obj = new Object() Object obj : 存放在java栈的本地变量表,作为reference类型 New Object() :创建的实例对象存放在java堆中,形成一块结构化内存 reference类型:指向java的对象位置有两种方式
-
- 句柄访问
优点:reference存放的稳定的句柄地址,对象被移动时(垃圾收集时比较普遍)只改变实例数据地址。
-
- 直接指针访问:
优点:速度更快,节省一次指针定位时间开销。
不足:由于对象访问在java非常频繁,这类开销积少成多也是很客观的时间成本。
3. jvm常见异常
参考https://blog.csdn.net/liu1390910/article/details/78825417 java.lang.OutOfMemoryError: 1. PermGen space: 永久代,jdk6及之前大多因为intern注入常量池导致,jdk7后会报Java heap space 2. Java heap space: JVM堆溢出 3. GC over head limit exceeded:高频GC,状态依然不佳 4. Direct buffer memory: 5. unable to create new native thread: 6. request {} byte for {}out of swap:地址空间不够而导致
三、JVM启动参数
- 参数举例
JAVA_OPTS="-server -Xmx4g -Xms4g -Xmn256m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Duser.timezone=GMT+8"
- 详解
-server//服务器模式 -Xmx4g //JVM最大允许分配的堆内存,按需分配 -Xms4g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次gc后JVM重新分配内存。 -Xmn256m //年轻代内存大小,整个JVM内存=年轻代 + 年老代 + 持久代 -Xss512k //设置每个线程的堆栈大小 -XX:+DisableExplicitGC //忽略手动调用GC, System.gc()的调用就会变成一个空调用,完全不触发GC -XX:+UseConcMarkSweepGC //并发标记清除(CMS)收集器 -XX:+CMSParallelRemarkEnabled //降低标记停顿 -XX:LargePageSizeInBytes=128m //内存页的大小 -XX:+UseFastAccessorMethods //原始类型的快速优化 -XX:+UseCMSInitiatingOccupancyOnly //使用手动定义初始化定义开始CMS收集 -XX:CMSInitiatingOccupancyFraction=70 //使用cms作为垃圾回收使用70%后开始CMS收集
四、JVM命令工具
调优建议:
如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化;如果GC时间超过1〜3 秒,或者频繁G C ,则必须优化。如果满足下面的指标,则一般不需要进行调优: ■ Minor GC执行时间不到50ms; ■ Minor GC执行不频繁,约10秒一次; ■ Full GC执行时间不到1s; ■ Full GC执行频率不算频繁,不低于10分钟1次。
- Jstat 详解:
-
总结垃圾回收情况 jstat -gcutil 20507
每隔2秒输出结果 jstat -gccause pid 2000
S0 — Heap上的 Survivor space 0 区已使用空间的百分比 S1 — Heap上的 Survivor space 1 区已使用空间的百分比 E — Heap上的 Eden space 区已使用空间的百分比 O — Heap上的 Old space 区已使用空间的百分比 P — Perm space 区已使用空间的百分比 M — 元空间 CCS — 压缩类空间利用率为百分比。 YGC — 从应用程序启动到采样时发生 Young GC 的次数 YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒) FGC — 从应用程序启动到采样时发生 Full GC 的次数 FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒) GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
- 元数据空间统计:jstat -gcmetacapacity pid
MCMN: 最小元数据容量 MCMX:最大元数据容量 MC:当前元数据空间大小 CCSMN:最小压缩类空间大小 CCSMX:最大压缩类空间大小 CCSC:当前压缩类空间大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
- 老年代内存统计:jstat -gcoldcapacity pid
OGCMN:老年代最小容量 OGCMX:老年代最大容量 OGC:当前老年代大小 OC:老年代大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
- 老年代垃圾回收统计;jstat -gcold pid
MC:方法区大小 MU:方法区使用大小 CCSC:压缩类空间大小 CCSU:压缩类空间使用大小 OC:老年代大小 OU:老年代使用大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
- 新生代内存统计:jstat -gcnewcapacity pid
NGCMN:新生代最小容量 NGCMX:新生代最大容量 NGC:当前新生代容量 S0CMX:最大Survivor1区大小 S0C:当前Survivor1区大小 S1CMX:最大Survivor2区大小 S1C:当前Survivor2区大小 ECMX:最大eden区大小 EC:当前ede区大小 YGC:年轻代垃圾回收次数 FGC:老年代回收次数
- 新生代垃圾回收统计:jstat -gcnew pid
S0C:Survivor1区大小 S1C:Survivor2区的大小 S0U:Survivor1区的使用大小 S1U:Survivor2区的使用大小 TT:对象在新生代存活的次数 MTT:对象在新生代存活的最大次数 DSS:期望的幸存区大小 EC:eden区的大小 EU:eden区的使用大小 YGC:年轻代垃圾回收次数 YGCT:年轻代垃圾回收消耗时间
- 类加载统计:jstat -class pid
Loaded:加载class的数量 Bytes:所占用空间大小 Unloaded:未加载数量 Bytes:未加载占用空间 Time:时间
- 编译统计:jstat -compiler pid
Compiled:编译数量。 Failed:失败数量 Invalid:不可用数量 Time:时间 FailedType:失败类型 FailedMethod:失败的方法
- jvm编译方法统计:jstat -printcompilation pid
Compiled:最近编译方法的数量 Size:最近编译方法的字节码数量 Type:最近编译方法的编译类型 Method:方法名标识
-
- Jps 进程状态jps -v 启动参数, jps -l 启动的进程id,启动类信息
-
Jmap:获取dump文件, jmap -F -dump:format=b,file=java_job_dump.bin 20507
- Jhat:分析dump文件,jhat+文件,jhat -J-Xmx512m <heap dump file>
- jstack
jstack [-l] <pid> (to connect to running process) 连接活动线程 jstack -F [-m] [-l] <pid> (to connect to a hung process) 连接阻塞线程 jstack [-m] [-l] <executable> <core> (to connect to a core file) 连接dump的文件 jstack [-m] [-l] [server_id@]<remote server IP or hostname> (to connect to a remote debug server) 连接远程服务器
- jstack检测cpu高
top top -H -p [pid] printf "%x\n" [pid] jstack [pid] | grep [tid] -A30
- 统计线程数
jstack -l [pid] | grep 'java.lang.Thread.State' | wc -l 或者: pstree -p [pid] | wc -l
- jstack检测cpu高