一, 手动编译 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, 状态依然不佳
- Direct buffer memory:
- 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] [[email protected]]<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
转载请注明地址: http://www.cnblogs.com/handsomecui/ https://www.cnblogs.com/handsomecui/
JVM 总结
来源: http://www.bubuko.com/infodetail-3678461.html