JVM线上调优
线上CPU占用过高
1.用top命令定位哪个进程对cpu占用过高 拿到进程id
2.top -Hp pid可以查看某个进程的线程信息,-H 显示线程信息,-p指定pid。
3.jstack 进程id 可以把进程中所有的线程列出来 此时列出来的线程编号是16进制的
4.步骤2的线程cpu过高id换算成16进制,即可定位步骤3线程详情
此时定位的线程大概率是waiting状态的
一定要找到是哪个线程持有这把锁 怎么找?搜索jstack dump的信息,找 ,看哪个线程持有这把锁RUNNABLE
线上堆内存占用过高
1.jps查看当前系统中有哪些java进程。
2 jmap查看堆内存占用情况(两种方式都可以)
2.1 jmap -histo 8867 | head -20 哪些对象占用空间最大
2.2最后jmap -dump:format=b,file=xxx pid 把当前内存快照一份,然后你去分析把
2.2的dump缺点 线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿2h(电商不适合)
1:设定了参数HeapDump,OOM的时候会自动产生堆转储文件
2:很多服务器备份(高可用),摘掉一台,用流量复制做重现
3:在线定位(一般小点儿公司用不到) arths
ps: jinfo+进程id可以查看虚拟机参数 启动命令等。
线上性能调优
YGC:年轻代耗尽时触发
FullGC:在老年代无法继续分配空间时触发,新生代老年代同时进行回收,所谓JVM调优就是尽量减少FGC
以CMS和G1
1. InitiatingHeapOccupancyPercent
有一个参数InitiatingHeapOccupancyPercent(in ni shou 哦 可 pan ci):老年代达到总空间多少的时候开始启动回收进程
因为有浮动垃圾的存在,所以CMS不能等老年代全满了才回收(会从年轻代过来浮动垃圾)
有个版本是90% 如果业务复杂,会很快填充到百分百,此时老年代满了之后 最夸张的是会用s o(serial old)单线程回收。
2. 调节新生代和老年代的比例
比如 hibernate框架中,老年代的对象多,可以把老年代比例增大一些