- ZGC现在只支持linux
Hotspot的参数分类
- 标准参数:-开头,所有Hotspot都支持
- 非标准参数:-X开头,特定版本Hotspot支持特定命令(参数)
- 不稳定的参数:-XX开头,下个版本可能取消
- 实验参数:好多是debug用的,一般我们用不上
java -version
java -X
内存会产生两种影响
- 内存泄漏memory leak
- 内存溢出out of memory
- 内存泄漏不一定产生内存溢出
- 两种常见的错误:
- OOM:OutOfMemoryError
- SOF:StackOverFlowError
- 注意异常的类型是Error,不是Exception
Hotspot参数的使用
- CMS的GC会更频繁!!!会有CMS详细的阶段过程(其实和PS+PO还是差不多的)
- 没满会被回收吗
GC的日志格式
java - Xmn10M - Xms40M - Xmx60M - XX:+PrintCommandLineFlags - XX:+PrintGCDetails HelloGC
- 日志会看起来很复杂,并且网上的信息也鱼龙混杂
- linux中的
time
命令—->time ls
- 表示用户态、内核态和总共的占用时间
- 最复杂的是heapdump的部分
- 当内存产生溢出之后,他会把整个堆给dump出来
- 挺麻烦的,详细解释如下:
- 一个eden加上from/to survivor中的一个是total,因为每次只能用一个(两个中的一个、其中之一)
高并发单机10k问题(这跟GC关系不大)
- 举例子时突然想到的架构问题!!!
- 目前已经被解决
- redis是其中的关键
- redis能撑住单机1w并发
- 每秒100w的并发—->100台机器装100个redis理论上就可以搞定了
- 任何一种架构也是和业务逻辑相关的,离了业务逻辑聊架构也是耍流氓
- 不同的架构是不同的业务逻辑
- 普通电商系统的业务逻辑:
- 下单
- 订单系统(IO)减库存
- 先把这件货占住,不能等到货没有了,还给别人生成订单
- 生成订单
- 等待用户付款
- 假如上述步骤是同步进行的,就是说等所有的步骤都完成了,即到了等待用户付款那一步才给用户反馈下单完成的信息,如果这算一个transaction的话(从逻辑上来说必须算一个transaction),非得按同步方式来运行,那么这个TPS撑不了几个,一秒钟几十个就可能会崩了
- 12306可能的模型是异步进行的,下完单后,一个线程去减库存,另一个线程直接将你的下单信息直接扔到kafka或者redis中去,直接给用户返回异步的“ok,下单成功,等待付款”
- 什么时候付完款了,订单处理线程就会去kafka或者redis中去拿数据,处理完一个就持久化一个,可以持久化到HBase中或者mysql中去
- 还有一些细节!!!—-> 库存的信息存哪,可以就把库存信息放在一台机器上,要减库存的时候就去那台机器上去减,rpc的一个远程访问—->这样这一台机器的负载也会重了,压在一台机器上是不合理的、不靠谱的
- 可以每台服务器留一部分票,就是说把票分下去
- 大流量的处理方法:分而治之(大原则)
- 1w张票,每台机器上放100张票,每个人只减自己的这部分库存
- 存在数据倾斜的问题怎么办呢???
- 即一台服务器很快没了,而另外的几台服务器还没少几张
- 一台很快就没了,但是另外几台很多人都抢不着
- 这时候还得有一台专门的服务器做他们之间的平衡(数据票的平衡)
- 观察各台服务器的票数—->这一台没了,就从另一边调一点票过去!!!
命令的使用
- 难在定位上而不是修正上!!!
jmap -histo ××× | head -20
:其中的-histo参数不是history,而是histogram,表示分析的图形化界面(图表)- jmap的坑:线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿(1个小时没有动,整个系统摊在那了)这里是指
jmap -dump:format=b, file=XXX pid
命令—->电商的系统不允许这么干 jmap -dump:format=b, file=XXX pid
在内存特别大的时候线上进行分析会有很大影响,可能会造成系统摊在那儿;而jmap -histo ××× | head -20
虽然对性能也有一些影响,但是相对来说是比较小的,还是可以去执行的,所以通过jmap -histo ××× | head -20
就基本可以定位了- 实际中用jmap生成堆转储文件是不行的,但是可以获取类的信息;不能用转储这个命令—->不能用转储这个命令
- 不能在线转储文件,但是可以在线定位!!!
- 怎么解决:
- 设定了参数HeapDump, OOM的时候会自动产生堆转储文件
-XX:+HeapDumpOnOutOfMemoryError
(不完善) - 很多服务器备份(高可用),停掉这台服务器对其他服务器不影响(不完善,但是可以说,是相对完善的一个说法,也不容易被面试官问出bug来)
- 可以这么说“我知道jmap在内存很大的时候会很慢,所以我们一般进行jmap的话会先对这台服务器做一个隔离,隔离完之后再进行jmap分析”!!!可以使用jmap在线定位
jmap -histo ××× | head -20
—->查找有多少对象产主 - 不能用
jmap -dump:format=b, file=XXX pid
- 🌟使用jmap在线定位
jmap -histo ××× | head -20
!!! - 在线定位:arthas在线排查!!!(用他来干)—->在线定位很困难,因此阿里做了很多工作(目前接触到的在线排查工具中最好用的,比国外的好用)(面试的时候说了麻烦???—->因为一般小点儿的公司用不到,说了容易露馅)—->尽量不要跟面试官说在线分析arthas,否则背调会比较严格
- 阿里的arthas没有提供jmap的功能,还是离不了jmap -histo 这条命令
- 设定了参数HeapDump, OOM的时候会自动产生堆转储文件
jmap可以手动导出堆转储文件,但线上内存特别大的时候一般不会这么干!!!
jmap -dump:format=b, file=XXX pid
java -Xms20M -Xmx20M -XX:+UseParallelGC -XX:+HeapDumpOnOutOfMemoryError com.mashibing.jvm.gc.T15_FullGC_Problem01
使用
MAT/jhat
进行dump堆转储文件的分析—->参考—->MAT不是很好用,要用的话直接jvisualvm就可以了,纯命令行也可以用jhat- 找到代码的问题并优化代码
- 一般的导出堆文件这件事
jmap -dump:format=b, file=XXX pid
在在线系统中不要轻易地这么干 - 定位到代码后改代码,改不了代码就改小环境
- 用图形界面在上线之前,甚至在上线地预运行期间或者内测期间,可以使用图形界面,正式上线之后用图形界面就比较少了
- 上线之后如何观察、定位、处理出现地问题呢—->阿里的arthas
Arthas
反编译
- 查看动态代理生成类的问题
- 第三方库的问题(观察)
- 检查版本是否正确替换并生效—->版本检查!!!
热替换
- 类似热部署的概念
- 当前只可以更换方法的实现,方法的名称等要完全一样(不能改方法名和属性,参数?)
- 原理:用ClassLoader重新redefine,ClassLoader里面有一个方法叫redefine;调AppClassLoader的redefine方法重新加载类
- 与jar包无关,这些class都是从jar包中load到内存中的,jar是不会load到内存中去的
- 现在热替换还有一些限制!!!
- 改多个文件热替换,很多个方法、对象时,只能改方法实现—->改了方法名的话,其他用到的地方(调用的地方)也要进行相应的改变,就更加麻烦了,这是不行的
- 计划中后面的版本能换方法名
Arthas没有包含jmap的功能
jmap -histo
就没有- 目前还不能完全替代jmap
OSGI也可以,监控JVM!!!
- 但是OSGI比较复杂
- 系统必须按照OSGI来构建才可以,可以很少有系统完全那么构建
trace
- sc search class找到特定的class的相关信息等或者脚本啥的
- watch 观察方法的**执行结果**!!!!