JVM总结
欢迎大家访问handsomecui的博客,转载请注明地址https://www.cnblogs.com/handsomecui,欢迎加入技术群讨论:778757421
一、手动编译JAVA
1 2 3 4 | 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对象时全过程
- 对象访问
1234
Object obj = new Object()
Object obj : 存放在java栈的本地变量表,作为reference类型
New Object() :创建的实例对象存放在java堆中,形成一块结构化内存
reference类型:指向java的对象位置有两种方式
-
- 句柄访问
优点:reference存放的稳定的句柄地址,对象被移动时(垃圾收集时比较普遍)只改变实例数据地址。
-
- 直接指针访问:
优点:速度更快,节省一次指针定位时间开销。
不足:由于对象访问在java非常频繁,这类开销积少成多也是很客观的时间成本。
3. jvm常见异常
1 2 3 4 5 6 7 8 | 参考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启动参数
- 参数举例
12345
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"
- 详解
123456789101112
-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命令工具
调优建议:
1 2 3 4 5 | 如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化;如果GC时间超过1〜3 秒,或者频繁G C ,则必须优化。如果满足下面的指标,则一般不需要进行调优: ■ Minor GC执行时间不到50ms; ■ Minor GC执行不频繁,约10秒一次; ■ Full GC执行时间不到1s; ■ Full GC执行频率不算频繁,不低于10分钟1次。 |
- Jstat 详解:
-
1
总结垃圾回收情况 jstat -gcutil 20507
1每隔2秒输出结果 jstat -gccause pid 2000
123456789101112S0 — 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
12345678910
MCMN: 最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
- 老年代内存统计:jstat -gcoldcapacity pid
12345678
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
- 老年代垃圾回收统计;jstat -gcold pid
12345678910
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
- 新生代内存统计:jstat -gcnewcapacity pid
1234567891011
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大Survivor1区大小
S0C:当前Survivor1区大小
S1CMX:最大Survivor2区大小
S1C:当前Survivor2区大小
ECMX:最大eden区大小
EC:当前ede区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数
- 新生代垃圾回收统计:jstat -gcnew pid
1234567891011
S0C:Survivor1区大小
S1C:Survivor2区的大小
S0U:Survivor1区的使用大小
S1U:Survivor2区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:eden区的大小
EU:eden区的使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
- 类加载统计:jstat -class pid
12345
Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间
- 编译统计:jstat -compiler pid
123456
Compiled:编译数量。
Failed:失败数量
Invalid:不可用数量
Time:时间
FailedType:失败类型
FailedMethod:失败的方法
- jvm编译方法统计:jstat -printcompilation pid
1234
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
12345678
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高
1234
top
top
-H -p [pid]
printf
"%x\n"
[pid]
jstack [pid] |
grep
[tid] -A30
- 统计线程数
123
jstack -l [pid] |
grep
'java.lang.Thread.State'
|
wc
-l
或者:
pstree -p [pid] |
wc
-l
- jstack检测cpu高
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架