jvm线上调优排查

-XX:+PrintHeapAtGC   每次GC后,都打印堆信息

-XX:+PrintGCDetails  程序结束之后打GC信息。

n Xloggc:log /gc.log 指定GC日志的路径,以文件输出

-XX:+TraceClassLoading  监控类加载       跟踪调试时, 看哪些类加载进来了

-XX:+PrintCLassHistogram  按下 Ctrl+Break后,打印类的信息

-Xmx  -Xms   最大堆  最小堆


-Xmn 设置新生代大小

-XX:NewRatio   老年代和新生代的比值。  

-XX:SurvivorRatio  表示了eden区和每一个survivor空间的比值


-XX:+HeapDumpOnOutOfMemoryError   OOM时导出堆到文件

-XX:HeapDumpPath=/zhoubin/xxx.dump  导出OOM的路径    注意权限

-XX:OnOutOfMemoryError=/zhoubin/jdk/bin/jstack -F %1> /zhoubin/xxx.sh   当程序OOM时,执行一件事,可以是通过jstack生成线程的dump,也可以发送邮件 重启等



总结

根据实际情况调整新生代和幸存代大小

官方推荐新生代占 3/8    幸存代占新生代的1/10 

在OOM时,记得Dump出堆,可以排查现场问题


永久带  方法区

-XX:PermSize -XX:MaxPermSize  设置永久区的初始空间和最大空间     超过max OOM

表示一个系统能容纳多少种类型, 一般几十M,最多百来M


栈  -Xss   通常几百K.  决定函数调用深度    局部变量,参数   每个线程都有独立的栈空间


20.Stop-The-world  java的一种全局暂停的现象    全局停顿 所有java代码停止,native代码可以执行,但不能和jvm交互

多半由GC引起:dump线程   死锁检查  堆dump

危害:a.长时间服务停止,没有响应  b.遇到HA系统 可能引起主备切换,严重危害生产环境。

新生代几次 0.0000x秒。   老年代GC时间久。          堆越大  GC 越长,要扫描


GC参数

21.   -XX:+UseSerialGC 串行回收器      新生代 老年代 都会用这个 

新生代  复制算法   老年代  标记压缩           效率高   多核无法利用这个优势  较长的停顿

22.ParNew并行收集器  -XX:+UseParNewGC    

特点 : 

新生代并行   老年代串行     

Serial收集器新生代并行版本  

复制算法  多线程,需多核支持  多线程不一定比单线程快。 设置合理的话,多CPU快。单CPU 建议用串行

-XX:ParallelGCThreads 限制并行收集垃圾的线程数

23.Parallel收集器

类似ParNew

新生代复制算法   老年代 标记 压缩

更加关注吞吐量

-XX:+UseParallelGC    使用Parallel收集器(新生代并行)+老年代串行

-XX:+UseParallelOldGC  使用Parallel收集器+老年代并行

24.并行回收器两个参数

-XX:MaxGCPauseMills   最大停顿时间, 单位毫秒  GC尽力保证回收时间不超过设定值

-XX:GCTimeRatio  0~100的取值范围   垃圾收集时间占总时间的比   默认99  即GC占 1% 

以上两个参数是矛盾的。停顿时间和吞吐量不能同时调优       吞吐量大:GC占CPU少   停顿时间短:GC次数多,占CPU多。

解决:发明新的GC算法, 将工作量减少

25.CMS 并发收集器  concurrent   mark  sweep  与用户线程一起执行 标记清除算法  老年代收集器   新生代用 parNew

-XX:+UseConcMarkSweepGC

特点:尽可能降低停顿   清理不彻底  影响系统整体吞吐量      

-XX:CMSInitiatingOccupancyFraction 设置触发GC的阈值     如果内存预留不够,则会引起 concurrent mode failure

会改用串行收集器作为后备收集器。  引起长时间停顿, 堆空间消耗殆尽,停顿时间长。

-XX:+UseCMSCompactAtFullCollection  FullGC后 进行一次整理

-XX:+CMSFullGCsBeforeCompaction  设置进行几次FullGC后,进行一次碎片整理

-XX:ParallelCMSThreads 设定CMS的线程数量   不宜太大  和cpu数目一致

26.碎片    标记清除(cms,更关注停顿,如果要压缩,因为清除阶段和应用程序一起工作,可能找不到内存中的对象)  标记压缩(串行,并行)   

27.从应用层减少GC压力

a.软件如何架构     

b代码如何编写

c堆空间如何分配



一个完整的案例:

查看容器   docker ps -a

进入容器: 

  1. $ sudo docker exec -it 775c7c9ee1e1 /bin/bash 

找到java进程  jps -m -l -v 

dump文件   sudo -u admin -H /opt/taobao/java/bin/jmap -dump:format=b,file=/home/admin/hicccloud/logs/cc.hprof 6

为什么要用admin, 因为程序是admin起的。



将远程的复制到本机        被复制的文件要有读权限

sudo scp -p21422  [email protected]:/tmp/aa.hprof /Users/zhoubin/IdeaProjects/hicccloud/

再导入eclipse中即可


打印GC时 将堆栈信息打出

-XX:+PrintHeapAtGC   每次GC后,都打印堆信息

-XX:+PrintGCDetails  程序结束之后打GC信息。


第二个完整的例子   查线程引起的异常

1.jps -m -l -v 查看进程   

2.首先看下机器是否装 pidstat     

可以安装

 在Debian/Ubuntu系统中可以使用下面的命令来安装

  # apt-get install sysstat

  CentOS/Fedora/RHEL版本的linux中则使用下面的命令:

  # yum install sysstat


pidstat  -p  [pid] -u  1   3  -t  看进程下每个线程的cpu  每秒更新一次, 一共3次

pidstat -p [pid] 1 3 -d -t   看每个线程的io  


如果没装pidstat    则用 ps -mp [pid] -o THREAD,tid,time 查线程cpu 

然后用jstack   

   jstack  [Tid ]  >>C:\a.txt    dump线程的jstack日志     然后拿到jstack 文件中 问题线程的 nid=XXX nid为容器外id  转为10进制
 

 printf 也可以哦,十六进制和十进制互相转换都没问题

    ]$ printf %d 0xac
    172
    ]$ printf %x 172

0xac










 





你可能感兴趣的:(JDK)