第八节 PS+PO调优
(1)HotSpot参数分类:
标准:-开头,所有hotspot都支持
非标准:-X开头
不稳定:-XX开头
(2)内存泄露:memory leak;程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费
内存溢出:out of memory 不断产生对象
(3)java -XX:PrintCommandLineFlags HelloGC 显示默认的参数(HelloGC 是jar包名字 )
command [kəˈmænd] 指令
(4) -Xmn10M 新生代的大小(n是new)
-Xms40M 最小堆的大小
-Xmx60M 最大堆的大小
最大堆的大小和最小堆大小一般设定为一样,不要让它产生弹性压缩,会浪费系统的宝贵资源,对象少的话还会收缩。
java -Xmn10M -Xms40M -Xmx40M -XX:PrintCommandLineFlags -XX:PrintGC HelloGC
-XX:PrintGC打印GC回收的信息
PrintGCDetails PrintGCTime -- 打印GC详细i信息
PrintGCCauses --- 打印GC产生的原因
(5) CMS日志信息: java -XX:ConcMarkSweepGC -XX:PrintCommandLineFlags HelloGC
(6) -XX:PrintGCDetails
allocation failure 分配失败
Times:整体时间 user--用户态时间;sys---内核态时间;real----总共占用时间
(7) -XX:PrintGCDetails 若产生内存溢出,显示heap dump信息
eden spase 8192k 94% used [地址1,地址2,地址3]
地址1:起始地址;地址2:使用空间结束地址; 地址3:整体空间结束地址
内存起始地址到整体 空间结束地址是5632k,占用94%
total = eden + 1个survivor
reserved[rɪˈzɜːvd] 保留;capacity [kəˈpæsəti] 容量 commit [kəˈmɪt]承诺;保证
capacity [kəˈpæsəti]容量
整个一大块内存(reserved),分成一块一块的,连续占用了3块(committed),在此3块里面,只使用一部分作为整体容量(capacity),此容量可弹性扩大,当前占用的部分是used
(8)吞吐量= 用户代码时间/(用户代码执行时间 + 垃圾回收时间)
响应时间 : STW越短,响应时间越好
吞吐量优先是只保证户线程,响应时间优先是保证stw短,回收快;两者是矛盾的,吞吐量多(内存大),响应时间就会边长,响应时间短,就会造成吞吐量少;
可以直接扩大内存然后改为使用G1。
CMS 和 pN 目前也还是有用的,CMS+PN的吞吐量比G1高,G1的响应时间比 PN+CMS要好.
G1比CMS+PN的吞吐量少15%,cpu大量的时间用在GC上
其实大部分的网站系统追求的都是响应时间
科学计算、数据挖掘 都是吞吐量优先
(9)OOM 是 out of memory
(10)1百万并发,只1百万个订单1秒种完成;
淘宝是一年最高是54W并发;1000的并发量已经很牛了,用户已经上几十万在线量了。
(11)JVM调优,要从业务场景开始,根据压力测试进行调优。
①先熟悉业务场景(选定垃圾回收器,没有最好的垃圾回收器,只有最合适的)
响应时间、停顿时间【GMS G1 ZGC】 (需要给用户响应)
吞吐量
②选择回收器组合
③ 计算内存需求(经验值 1.5G 16G) 内存需求弹性大,内存小、回收快也可以。
④ 选定CPU(按预算,越高越好)
⑤ 设定年代大小、升级年龄
⑥ 设置日志参数
-Xloggc:/opt/xxx/logs/xxx-xxx-gc-%t.log 设置日志地址名字
-XX:+UseGCLogFileRotation 循环写入 rotation [rəʊˈteɪʃn] 旋转
-XX:NumberofGCLogFiles=5 文件个数是5
-XX:GCLogFilesSize=20M 每个 文件20M
日志最大是100M,循环写入
(12)GC调优分为三类:
① 根据需求进行JVM规划和调优
② 优化运行jvm运行环境(慢、卡顿)
③ 解决JVM运行过程中出现的各种问题 (OOM)
(13)预调优案例:垂直电商,最高每日百万订单,处理订单系统需要什么样的服务器 配置 ?
这个问题比较业余,因为很多不同的服务配置都能支撑(1.5G可以,16G也可以)。
每天一百万订单,每小时不会产生很高的并发量,我们寻找高峰时间,假如有2个小时高峰期,有72万的订单,平均一小时36万,1秒产生订单1000.
内存选择大小按照巅峰时选择。
好多时候就是经验值拿来做压力测试,实在不行就加cpu加内存。
非要计算的话,就看一个订单的产生需要多少内存,1M很多了,比如需要512k,1000个订单就是500M,将eden设为500m,完全可以设为250m,边进内存边回收 --- -完全预估想像
应该专业一点问:要求响应时间缩少,比如100ms-----进行压测 (100ms很长了)
回答此问题:找到最高峰时段的订单数..1000个/s, 500M..,也要看cpu的算力和内存的大小,超级大内存肯定是没问题的,20G内存,每秒500M往里面扔,扔满YGC搞定,小的内存也可以,填满一半内存,就GC把前面垃圾回收了。挑一个市面上性价比高的服务器进行压测,不行就加内存加cpu,实在不行就上云服务器。
(14)12306遭遇春节大规模抢票应该如何支撑?
号称最高并发量100W
CDN -> LVS -> NGINX -> 业务系统 -> 每台机器1W并发(10k问题--redis),100台机器
100台机器 装100个redis 可以支撑100W最高
业务中:电商订单 -> 下单 -> 订单系统(IO)减库存 ->等待用户付款
12306可能的模型:减库存和等待用户付款需要异步处理->等待付款 (下单信息放过到redis中,付款成功后,再持久化入)
大流量的处理方法:分而治之
比如订单库存减1问题,100台机器,每台100张票,需要另外一台机器进行均衡,比如有一台机器只剩10张票,其他机器有90张,需要协调将票数均匀到10张票的那个机器一下。
(15) 优化环境
有一个50万PV的资料网站(从磁盘提取文档到内存)原服务器32位,1.5G的堆,用户反馈网站比较缓慢
①为什么原网站慢---很多用户浏览 数据,很多数据load到内存,内存不足 ,频繁GC,响应时间变慢。
②升级到64位,16G内存,但卡顿十分严重,比以前效率更低
内存越大FGC时间越长
③调优:PS换成 PN+ CMS 或者 G1
ps+po 只要内存大,卡顿就会十分严重
从业务上调优--文档走别的服务器
第八节 解决JVM运行过程中出现的各种问题
一、系统CPU经常100%,如何调优
(1)一般是运维团队首先收到报警信息(CPU Memory)
(2)程序员检查:
命令:top 查看耗费cpu的进程
1591的进程 cpu最高
(3)命令 top -Hp 1591 显示 1591进程里面所有的线程
垃圾回收的线程占用会非常高,实际的时候会是业务逻辑的线程占用会非常高
(4) 命令: jstack 1591 -- 也是显示1591的所有线程(线程号nid显示为16进制,top显示的线程号是十进制)
java.lang.Thread.State 重要,state好多是waiting,就是有问题
命令:jps -- java的进程
jstack jps linux和windows都可用
jsp定位具体java进程
jstack定位线程状况,重点关注:WAITING BLOCKED
例如上图中 waiting on<0X0000....33310> ,
假如有一个进程中100个线程,很多线程都在waiting on<xx>, 一定要找到是哪个线程持有这把锁。
怎么找?----搜索jstack dump的信息,找<xx> ,看哪个线程持有这把锁,这个线程一般是RUNNABLE状态(死锁,无限循环中)
jstack 可以定位到哪行代码
阿里规范中规定,线程的名称(尤其是线程池),都要写有意义的名称,方便日志查错误。
如何定义线程池的线程名称---自定义ThreadFactory
(5) 命令:jinfo 1591 ---- 显示进程的具体信息
JVM的信息、classpath有哪些
(6)命令: jstat -gc 1591 ---- -动态观察gc情况/阅读GC日志发现频繁GC
arthas/ jconsole/ jprofiler(要钱,最好用)
jstat -gc 1591 500 --- 每500个毫秒打印一遍
包括各种内存区域的大小、GC的次数
格式不直观,用的不太多
(7)命令: jconsole --jdk自带的命令 - 远程监控
jdk的安装bin目录中,jconsole.exe/jvisualvm.exe 这两个都是类似的,
windows远程连接linux中java进程,需要开启一个服务端口给windows。
jmx是java标准的访问远程服务的协议,Java Management Extensions,将linux服务的jmx打开即可(就是在服务启动的时候,添加参数)。
现在jconsole用的少了,页面简陋,用的jvisualvm较多
(8) jvisualvm.exe
面试的时候问如何定位OOM问题的,不能说是通过图形界面进行查问题的。
jmx是开的进程,用了cpu,影响服务器性能
已经上线的系统不用图形界面用什么:cmdline arthas
图形界面用在什么地方:测试! 测试的时候进行监控(压测观察)
(9) 命令:jmap -histo 4655 | head -20 (前20行,histo指图形界面)
可以在线上运行此命令,也会影响cpu,但是不大。
(10) 命令:jmap -dump:format=b,file=xxx pid
线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿(电商不适合)
面试时回答方式有三种:
①设定了参数HeapDump,OOM的时候自动产生堆转储文件
② 很多服务备份(高可用),停掉这台服务器对其他服务器不影响,停掉以后执行此命令
③在线定位(一般小公司用不到)
(11)数据库连接池 ,要在连接池的日志中查看,jstack看不到原因
(12) 线上查问题时:运维团队报告cpu高内存满-->top/jps找到哪一线程--->jstack 看哪一线程有问题----> 如果多的线程是垃圾回收线程,则频繁GC,去看GC日志------>Jmap查看哪一对象占用太多