jvm内存调整过程中,我们经常使用的参数就是:
-Xms 为jvm启动时分配的内存,比如-Xms200m,表示分配200M --最小堆内存
-Xmx 为jvm运行过程中分配的最大内存,比如-Xms500m,表示jvm进程最多只能够占用500M内存 --最大堆内存
-Xss 为jvm启动的每个线程分配的内存大小,默认JDK1.4中是256K,JDK1.5+中是1M --设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M
一般jvm出现Cannt’ allocate memory的错误就是机器的内存不够,导致系统无法为jvm分配给定的内存,这个在启动时犹未突出,所以会在启动参数中设置-Xms来指定;而 OutOfMemoryError错误则一般会在系统运行一段情况后出现,绝大部分也是机器内存不够或是JVM本身的内存空间已被用尽,这时就要根据情况 进行调整了,如果是JVM本身的内存空间用尽,则需要调整-Xmx参数来分类jvm的可用内存,如果是机器内存不够则要增加内存或是调优程序了。
mat内存分析工具
参数说明
-Xmx3550m:设置JVM最大堆内存为3550M。
-Xms3550m:设置JVM初始堆内存为3550M。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xss128k:设置每个线程的栈大小。JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K。应当根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。需要注意的是:当这个值被设置的较大(例如>2MB)时将会在很大程度上降低系统的性能。
-Xmn2g:设置年轻代大小为2G。在整个堆内存大小确定的情况下,增大年轻代将会减小年老代,反之亦然。此值关系到JVM垃圾回收,对系统性能影响较大,官方推荐配置为整个堆大小的3/8。
-XX:NewSize=1024m:设置年轻代初始值为1024M。
-XX:MaxNewSize=1024m:设置年轻代最大值为1024M。
-XX:PermSize=256m:设置持久代初始值为256M。
-XX:MaxPermSize=256m:设置持久代最大值为256M。
-XX:NewRatio=4:设置年轻代(包括1个Eden和2个Survivor区)与年老代的比值。表示年轻代比年老代为1:4。
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的比值。表示2个Survivor区(JVM堆内存年轻代中默认有2个大小相等的Survivor区)与1个Eden区的比值为2:4,即1个Survivor区占整个年轻代大小的1/6。
-XX:MaxTenuringThreshold=7:表示一个对象如果在Survivor区(救助空间)移动了7次还没有被垃圾回收就进入年老代。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代,对于需要大量常驻内存的应用,这样做可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代存活时间,增加对象在年轻代被垃圾回收的概率,减少Full GC的频率,这样做可以在某种程度上提高服务稳定性。
windows idea
E:\idea_workspace\xxx>
E:\idea_workspace\xxx>jinfo -flag MetaspaceSize 16676
-XX:MetaspaceSize=21807104
E:\idea_workspace\xxx>jinfo -flag MaxTenuringThreshold 16676
-XX:MaxTenuringThreshold=15
E:\idea_workspace\xxx>jinfo -flag InitialHeapSize 16676
-XX:InitialHeapSize=266338304
E:\idea_workspace\xxx>jinfo -flags 16676
Attaching to process ID 16676, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.202-b08
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=266338304 -XX:MaxHeapSize=4255121408 -XX:MaxNewSize=1418199040 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88604672 -XX:OldSize=177733632 -XX:+UseCompressedClassPointer
s -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line: -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:56509,suspend=y,server=n -javaagent:D:\dev\idea\lib\rt\debugger-agent.jar=file:/C:/Users/Administrator/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8
java -XX:+PrintFlagsInitialI
java -XX:+PrintFlagsFinal
java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=265928832 -XX:MaxHeapSize=4254861312 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
# 常用的jvm配置
-Xms128m -Xmx4096m -Xss1024k -XX:MetaspaceSize=1024m -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseParallelGC
#-Xms10m -Xmx10m -XX:+PrintGcDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC (ParNew+Tenured)
#-Xms10m -Xmx10m -XX:+PrintGcDetails -XX:+PrintCommandLineFlags -XX:+UseG1GC
#配置结果
-XX:InitialHeapSize=134217728 -XX:MaxHeapSize=4294967296 -XX:MetaspaceSize=1073741824 -XX:+PrintCommandLineFlags
-XX:+PrintGCDetails -XX:ThreadStackSize=1024 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseSerialGC
落地实现(默认垃圾收集器):
串行回收-XX:+UseSerialGC
并行回收-XX:+UseParallelGC
并发回收CMS(ConcMarkSweep)
G1
Java命令行监控工具(jmap,jstack,jstat,jinfo,jps)
查看cup核心数量
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq
# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l
生产环境服务器变慢,诊断思路和性能评估
#整体查看top
#CPU消耗查看 vmstat
#vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析
vmstat-n 2 3
#一般vmstat工具的使用是通过两个数字参数来完成的,第一个参数是采样的时间间隔数单位是秒,第二个参数是采样的次数
# - procs
# r:运行和等待CPU时间片的进程数,原则上1核的CPU的运行队列不要超过2,整个系统的运行队列不能超过总核数的2倍,否则代表系统压力过大
# b:等待资源的进程数,比如正在等待磁盘I/0、网络I/0等。
# - cpu
# us:用户进程消耗CPU时间百分比,us值高,用户进程消耗CPU时间多,如果长期大于50%,优化程序;
# sy:内核进程消耗的CPU时间百分比:
# us +sy参考值为80%,如果us+sy大于80%,说明可能存在CPU不足。
# id:处于空闲的CPU百分比.
# wa:系统等待IO的CPU时间百分比.
# st:来自于一个虚拟机偷取的CPU时间的百分比
#查看额外的情况:
mpstat -P ALL 2 #查看多核CPU核心的当前运行状况信息, 每2秒更新一次
#每个进程使用cpu的用量分解信息 pidstat 是sysstat软件套件的一部分
pidstat -u 1 -p (进程id)
#-u:默认的参数,显示各个进程的cpu使用统计 每隔1s更新一次
#-p:指定进程号
#内存消耗查看 free
free -m
#查看额外
pidstat-p 进程号 -r 采样间隔秒数
#硬盘查看 df
df -h
#磁盘io查看 iostat
#iostat用于报告中央处理器(CPU)统计信息和整个系统、适配器、tty 设备、磁盘和 CD-ROM 的输入/输出统计信息
#用到iostat,ifstat,mpstat,sar等命令,系统中默认没这些命令,
#想用yum install iostat类似的命令来安装,这些命令都在sysstat这个包里,用以下命令安装就行了
#yum install sysstat
iostat -xdk 2
#-x 输出扩展信息.
#-d 仅显示磁盘统计信息.与-c选项互斥.
#-k 以K为单位显示每秒的磁盘请求数,默认单位块.
#查看额外
-pidstat-d 采样间隔秒数 -p 进程号
#磁盘块设备分布rkB/s每秒读取数据量kB;
#wkB/s每秒写入数据量kB;
#svctm/o请求的平均服务时间,单位毫秒;Iawait/O请求的平均等待时间,单位毫秒;值越小,性能越好;
##util 一秒中有百分几的时间用于I/O操作。接近100%时,表示磁盘带宽跑满,需要优化程序或者增加磁盘;
#rkB/s、wkB/s根据系统应用不同会有不同的值,但有规律遵循:长期、超大数据读写,肯定不正常,需要优化程序读取。
#svctm的值与await的值很接近,表示几乎没有I/O等待,磁盘性能好,
#如果await的值远高于svctm的值,则表示I/O队列等待太长,需要优化程序或更换更快磁盘。
#网络io ifstat 默认情况下系统没有,需要安装
linux查看占用cpu最高的进程
#1 先用top命令找出CPU占比最高的 看是不是所运行的java项目
top
#2 ps-ef或者jps进一步定位,得知是一个怎么样后台程序
ps -ef|grep java
#或 jps -l
#3 定位到具体线程或者代码
top -p (进程id) -H
#-p 用于指定进程,-H 用于获取每个线程的信息,从 top 输出的内容,可以看到有哪几个线程占用非常高的 CPU:
#或 ps -mp (进程id) -o THREAD,tid,time #看对应的占用cpu高的tid
#4 将需要的线程ID转换为16进制格式(英文小写格式)
printf "%x\n" (线程id) #或用程序计算器 注意:程序计算器显示是大写字母
#5 jstack 进程ID|greptid(16进制线程ID小写英文)-A60
jstack -l (线程id) #找到对应的java项目的哪个行代码
man 命令 显示该命令的使用参数
或 命令 --help
通过使用-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
IDEA打印出了源代码的汇编指令。