-
空间换时间:使用内存或者磁盘,换取更宝贵的CPU 或者网络,如缓存的使用; -
时间换空间:通过牺牲部分 CPU,节省内存或者网络资源,如把一次大的网络传输变成多次; -
其他诸如并行化、异步化、池化技术等。
-
正则操作 -
数学运算 -
序列化/反序列化 -
反射操作 -
死循环或者不合理的大量循环 -
基础/第三方组件缺陷
-
首先使用 free 查看当前内存的可用空间大小,然后使用 vmstat 查看具体的内存使用情况及内存增长趋势,这个阶段一般能定位占用内存最多的进程; -
分析缓存 / 缓冲区的内存使用。如果这个数值在一段时间变化不大,可以忽略。如果观察到缓存 / 缓冲区的大小在持续升高,则可以使用 pcstat、cachetop、slabtop 等工具,分析缓存 / 缓冲区的具体占用; -
排除掉缓存 / 缓冲区对系统内存的影响后,如果发现内存还在不断增长,说明很有可能存在内存泄漏。
-
通过 jmap 定期输出堆内对象统计,定位数量和大小持续增长的对象; -
使用 Profiler 工具对应用进行 Profiling,寻找内存分配热点。
-
使用工具输出磁盘相关的输出的指标,常用的有 %wa(iowait)、%util,根据输判断磁盘 I/O 是否存在异常,譬如 %util 这个指标较高,说明有较重的 I/O 行为; -
使用 pidstat 定位到具体进程,关注下读或写的数据大小和速率; -
使用 lsof + 进程号,可查看该异常进程打开的文件列表(含目录、块设备、动态库、网络套接字等),结合业务代码,一般可定位到 I/O 的来源,如果需要具体分析,还可以使用 perf 等工具进行 trace 定位 I/O 源头。
- 一次传输的对象过大,可能会导致请求响应慢,同时 GC 频繁;
- 网络 I/O 模型选择不合理,导致应用整体 QPS 较低,响应时间长;
- RPC 调用的线程池设置不合理。可使用 jstack 统计线程数的分布,如果处于 TIMED_WAITING 或 WAITING 状态的线程较多,则需要重点关注。举例:数据库连接池不够用,体现在线程栈上就是很多线程在竞争一把连接池的锁;
- RPC 调用超时时间设置不合理,造成请求失败较多;
Java 应用的线程堆栈快照非常有用,除了上面提到的用于排查线程池配置不合理的问题,其他的一些场景,如 CPU 飙高、应用响应较慢等,都可以先从线程堆栈入手。
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
jmap –histo:live $pid | sort-n -r -k2 | head-n 50
#内存ps axo %mem,pid,euser,cmd | sort -nr | head -10#CPUps -aeo pcpu,user,pid,cmd | sort -nr | head -10
grep "cpu " /proc/stat | awk -F ' ' '{total = $2 + $3 + $4 + $5} END {print "idle t usedn" $5*100/total "% " $2*100/total "%"}'
jstack $pid | grep java.lang.Thread.State:|sort|uniq -c | awk '{sum+=$1; split($0,a,":");gsub(/^[ t]+|[ t]+$/, "", a[2]);printf "%s: %sn", a[2], $1}; END {printf "TOTAL: %s",sum}';
6)查看最消耗 CPU 的 Top10 线程机器堆栈信息
# 1. 收集应用运行时的堆栈和符号表信息(采样时间30秒,每秒99个事件);sudo perf record -F 99 -p $pid -g -- sleep 30; ./jmaps # 2. 使用 perf script 生成分析结果,生成的 flamegraph.svg 文件就是火焰图。sudo perf script | ./pkgsplit-perf.pl | grep java | ./flamegraph.pl > flamegraph.svg
for file in /proc/*/status ; do awk '/VmSwap|Name|^Pid/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 3 -n -r | head -10
#显示最后一次或当前正在发生的垃圾收集的诱发原因jstat -gccause $pid #显示各个代的容量及使用情况jstat -gccapacity $pid #显示新生代容量及使用情况jstat -gcnewcapacity $pid #显示老年代容量jstat -gcoldcapacity $pid #显示垃圾收集信息(间隔1秒持续输出)jstat -gcutil $pid 1000
# 快速杀死所有的 java 进程ps aux | grep java | awk '{ print $2 }' | xargs kill -9 # 查找/目录下占用磁盘空间最大的top10文件find / -type f -print0 | xargs -0 du -h | sort -rh | head -n 10
6. 总结
本文来源于:90%的人会遇到性能问题,如何用1行代码快速定位?-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
-
- 加入Q群
- QQ扫一扫
-
评论