Bootstrap

20191111 jvm虚拟机调优

CPU报警,有哪些原因? 大量的计算; 内存报警,有哪些原因? 大量的文件读写;  如何排查问题?

现象:CPU报警,使用率高达90%.

CPU报警期间----->当前哪个接口调用次数最高(通过cat进行监控)----->当前接口做了哪些业务处理?是否可以使用缓存处理进行优化?(CPU高的常规原因有哪些:里面是否有for循环,是否进行大量的对象创建,是否频繁触发Full GC)

哪个进程占用的cpu最高? 哪个线程占用的cpu最高?

mysql服务占用CPU很高,建议项目应用不要和mysql占用同一台服务器,Mysql需要单独部署在某台机器上Mysql也要做HA

是mysql积压导致CPU处理不过来,后续队列里面的其他进程CPU占用也会升高。先处理最高的。

CPU消耗应该上下起伏并且不高于80%的;

最常见的一个场景是程序的线程或进程数过多。

 

如何查看某个进程的cpu占用率?top命令;如何查看线程的cpu占用率?top -Hp pid命令

pid,tid线程id。 进程中全部都是线程。

打印出某个进程中所有线程的cpu消耗状态。

ps -mp 28358 -o THREAD,tid,time

ps -aux 详细信息包含cpu,内存

ps -mp pid -o THREAD,tid,time | sort -rn:查看指定进程中各个线程占用CPU的状态,选出耗时最多、最繁忙的线程id。

 

当前进程消耗的cpu占比,内存占比? top命令,pid,USER(进程名称)

当前系统的内存大小Mem total;已经使用内存,空余内存。(内存和cpu)

 

查看各个进程的cpu使用情况,默认按cpu使用率排序;

结束掉异常进程:kill -9 pid  ;

top -Hp pid 查看该进程下各个线程的cpu使用情况。

如何把某个线程信息打印到文件里?

上图中可以看出pid为25077的线程占了较多的cpu资源,利用jstack命令可以继续查看该线程当前的堆栈状态。

 

jstack -F pid:打印出某个进程中的线程信息。 线程和内存堆栈之间的关系。

jstack -F pid >> 20191014.txt 查看内存快照。

在dump中,线程一般存在如下几种状态:

1、RUNNABLE,线程处于执行中;

2、BLOCKED,线程被阻塞;

3、WAITING,线程正在等待.

 

jstack定位cpu高占用

1、top命令找出最高占用的进程(command为java)

2、输入:top -H -p PID 或 ps -mp PID -o THREAD,tid,time

找出最高占用的线程并记录thread_id

3、使用命令将pid转换为十六进制(为什么需要将pid转化为16进制?

printf "%X\n" thread_id

4、查看dump信息(-a 30 意思打印30行)

jstack pid |grep 16进制的thread_id -a 30

或者导出

jstack pid |grep 16进制的thread_id -a 30 > xx.log 29049。

 

CPU占用过高的可能原因(哪些代码正在进行大量的计算)

1、代码中写死循环时,一直占用cpu;如果加上线程睡眠时间,则释放cpu占用,不会一直抢占cpu;

2、在循环中不停的创建对象,也会导致GC频繁;

3、FullGC。

 

常用命令: 进程,线程,虚拟机参数,垃圾收集状况

jps:本地所有的jvm进程。

jsp -v:查看虚拟机的参数配置。

jinfo -flags vmid;查看和调整虚拟机参数,虚拟机参数。

jstack -F vmid;jstack用于生成java虚拟机当前时刻的线程快照。打印线程信息,看看那些代码阻塞了线程。

jstat -gcutil 进程id 1000 10(每秒打印一次,打印十次,运行时堆栈信息,和垃圾回收机制有关系) 

jstat -gcutil 12682 1000 10

 

S0:幸存1区当前使用比例

S1:幸存2区当前使用比例

E:伊甸园区使用比例

O:老年代使用比例

M:元数据区使用比例

CCS:压缩使用比例

YGC:年轻代垃圾回收次数 (累计回收次数)

FGC:老年代垃圾回收次数

FGCT:老年代垃圾回收消耗时间

GCT:垃圾回收消耗总时间 y+f

(当前区域使用比例,Ed区域,幸存1区,幸存2区,老年代,垃圾回收次数,垃圾回收消耗时间)

本地可以跑,已发布到线上就有问题 怎么解决? 怎么打印线程信息?

杀死pid进程,kill pid;

 

case1: jvm启动内存参数小,导致响应时间长

现象:工作站有一会偶尔加载很慢,通过抓包显示接口响应时间为3秒。

原因:Doctor微服务有一台机器,启动内存参数太小,导致响应时间比较长;现在已经对虚拟机参数进行了优化,服务重启,响应正常。

启动参数小:导致第一次压测时tps比较低,并且也受到缓存的影响。

通过调节启动内存的大小,解决接口响应慢的问题

 

内存大小对性能的影响(机器处理任务的速度)

内存大小决定了机器的速度,严重时内存小还能造成死机。简单的说,比如你用水桶打水往水缸里倒,内存就相当于你的水桶。水桶越大,每次打的水就越多,你越能快速把水缸罐满。内存越大,电脑在单位时间内可同时存储的文件就越多,可以加快处理的进程。

由于CPU只能直接处理内存中的数据,所以内存的速度和大小对计算机性能的影响是相当大的。

内存的大小决定了电脑反应的速度。其实在实际使用中,很多软件对内存容量的依赖非常大,尤其是多种程序同时运行,内存容量不够是不行的,所以目前内存容是越大越好。

 

如何查看虚拟机参数?

把虚拟机参数配置到配置文件中,然后虚拟机启动的时候就会加载配置文件,配置就能够生效

微服务启动的时候,设置虚拟机参数

常用命令:

jps

jinfo 25548

jinfo -flags 25548

 

如何查看可用内存?

top命令,KiB Mem : 3882204 total 1g=1024m 1m=1024kb

3882204/1024/4 初始内存的大小。最大内存和初始内存都设置为1024m左右。

 

虚拟机参数设置标准

设置多大才算合理,标准是什么?

堆分配参数总结:

-Xms:表示java虚拟机堆区内存初始内存分配的大小,通常为操作系统可用内存的1/64大小即可

-Xmx:表示java虚拟机堆区内存可被分配的最大上限,通常为操作系统可用内存的1/4大小。但是开发过程中,通常会将 -Xms 与 -Xmx两个参数的配置相同的值,其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源。

一般来讲对于堆区的内存分配只需要对上述两个参数进行合理配置即可。

 

XX:NewSize : 设置新生代的大小

XX:NewRatio:设置老年代与新生代的比例,即老年代除以新生代大小

XX:SurviorRatio:新生代中eden区与survivior 区的比例

-XX:PermSize:设置永久区的大小

-XX:TargetSurvivorRatio:设置survivior 的使用率。当达到这个空间使用率时,会将对象送入老年代。

 

方法区参数配置

-XX:PermSize:表示非堆区初始内存分配大小,其缩写为permanent size(持久化内存)

-XX:MaxPermSize:表示对非堆区分配的内存的最大上限

 

例子:-Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m

上面设置的参数就是堆初始化128M,最大堆内存是512M;方法区初始化分配内存128M,方法区最大上限是512M。

 

;