调优前的基础概念:
- 吞吐量:用户代码时间 /(用户代码执行时间 + 垃圾回收时间)
- 响应时间:STW越短,响应时间越好
设置GC日志
循环输出
-Xloggc:/opt/xxx/logs/xxx-xxx-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause
优化环境
- 有一个50万PV的资料类网站(从磁盘提取文档到内存)原服务器32位,1.5G
的堆,用户反馈网站比较缓慢,因此公司决定升级,新的服务器为64位,16G
的堆内存,结果用户反馈卡顿十分严重,反而比以前效率更低了- 为什么原网站慢?
很多用户浏览数据,很多数据load到内存,内存不足,频繁GC,STW长,响应时间变慢 - 为什么会更卡顿?
内存越大,FGC时间越长 - 咋办?
PS -> PN + CMS 或者 G1
- 为什么原网站慢?
- 系统CPU经常100%,如何调优?(面试高频)
CPU100%那么一定有线程在占用系统资源,- 找出哪个进程cpu高(top)
- 该进程中的哪个线程cpu高(top -Hp)
- 导出该线程的堆栈 (jstack)
- 查找哪个方法(栈帧)消耗时间 (jstack)
- 工作线程占比高 | 垃圾回收线程占比高
- 系统内存飙高,如何查找问题?(面试高频)
- 导出堆内存 (jmap)
- 分析 (jhat jvisualvm mat jprofiler … )
- 如何监控JVM
- jstat jvisualvm jprofiler arthas top…
top会列出所有进程
jps只列出java进程
TOP命令使用
1.top查看当前CUP/内存使用情况
2.shift + M 内存排序
3.shift + T CPU 排序
4. top -Hp pid 查看线程
top -Hp 7635
jstack使用
jstack 定位线程状况,重点关注:WAITING BLOCKED
eg.
waiting on <0x0000000088ca3310> (a java.lang.Object)
假如有一个进程中100个线程,很多线程都在waiting on ,一定要找到是哪个线程持有这把锁
怎么找?搜索jstack dump的信息,找 ,看哪个线程持有这把锁RUNNABLE
jmap使用
1.查找前20对象
jmap - histo 4655 | head -20,查找有多少对象产生
2.dump文件
jmap -dump:format=b,file=xxx pid :
线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿(电商不适合)
(1)设定了参数HeapDump,OOM的时候会自动产生堆转储文件
(2)很多服务器备份(高可用),停掉这台服务器对其他服务器不影响
(3)在线定位(一般小点儿公司用不到)
jinfo
查看环境变量
dump文件几种方式
1.jmap
2.arthus heapdump
3.系统出现oom时
java -Xms20M -Xmx20M -XX:+UseParallelGC -XX:+HeapDumpOnOutOfMemoryError com.test
解析dump文件的几种方式
1.jhat
(1)jhat
/opt/kafka/test$ jhat -port 7777 a.dump
(2)通过7777端口,在浏览器上访问2.jvisualvm.exe
在线读取
注:远程读取需要jmx
1.jconsole
java -Djava.rmi.server.hostname=192.168.17.11 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=11111 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false XXX
2.jvisualvm
JVM参数设置
XX:PretenureSizeThreshold 的意思是超过这个值的时候,对象直接在old区分配内存
默认值是0,意思是不管多大都是先在eden中分配内存