jvm优化基本命令和工具的使用

1、必要性

在生产环境中可能会出现应用无反应,CPU飙升,内存占用太大等问题,可以从jvm的角度考虑。

2、jvm参数

2.1 jvm参数分为三种:

  • 标准参数
    -help
    -version
  • -X参数(非标准参数)
    -Xint
    -Xcomp
  • -XX参数(使用率较高)
    -XX:newSize
    -XX:UseSerialGC

2.2 标准参数
jvm的标准参数一般都很稳定,在未来的jvm版本中不会改变,可以使用java -help查看所有标准参数。
如:-help,-version,-D<名称>=<值>
2.3 非标准参数
jvm的-X参数是非标准参数,在不同的jvm版本中,参数可能会不同,可以使用java -X查看非标准参数。
如:-Xint,-Xcomp,-Xmixed
2.4 -XX参数
-XX参数也是非标准参数,主要用于jvm调优和dubug操作。
-XX参数的使用有两种类型,一种是boolean类型,一种是非boolean类型。

  • boolean模式
    -XX:[±]< name >表示启用或禁用name属性。
    如-XX:+DisableExplicitGC,表示禁止手动调用gc操作,也就是说System.gc()无效。
  • 非boolean模式
    -XX:< name >=< value > 表示name属性的值为value
    如:-XX:NewRatio=1 表示新生代和老年代的比值
    2.5 -Xms和-Xmx参数
    -Xms和-Xmx分别是失职jvm堆内存初始值和最大值。
    -Xmx2048m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。
    -Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。
    2.6 查看jvm运行参数
  • 运行java命令时打印出运行参数
    只需要添加-XX:+PrintFlagsFinal参数即可。
    如java -XX:+PrintFlagsFinal -version
    在这里插入图片描述
    由上述的信息可以看出,参数有boolean类型和数字类型,值的操作符是=或:=,分别代表默认值和被修改的值。
  • 查看正在运行的java进程的参数
    这种情况下需要借助jinfo命令查看。
    查看所有参数方法:jinfo -flags <进程id>
    在这里插入图片描述
    查看某一个参数:jinfo -flag <参数名> <进程id>
    在这里插入图片描述

3、jvm内存模型

jvm内存模型在1.7和1.8版本之间有较大变化。
3.1 jdk1.7内存模型
在这里插入图片描述

  • Young 年轻代
    年轻代被划分成三个区,Eden和两个大小严格相同的Survivor区,Survivor区,同一时刻只有一个区被使用,另一个用于垃圾收集时复制对象使用。当Eden区变满时,GC就会把Eden中存活的对象复制到Survivor区,根据JVM的策略,在经过几次垃圾回收之后依然存活的对象会被转移到Tenured区。
  • Tenured 老年代
    主要用于保存生命周期较长的对象,当年轻代对象在多次垃圾回收之后依然存活就会被转移到Tenured区,一些大对象也会直接被分配在Tenured区。
  • Perm 永久代
    主要用于保存class,method,filed对象。这部份的空间一般不会溢出,除非一次性加载了很多的类。或者热部署时重新部署后,类的class没有被卸载掉,造成了大量的class对象保存在了perm中。
  • Virtual区
    最大内存和初始内存的差值。
    3.2 jdk1.8内存模型
    在这里插入图片描述
    年轻代:Eden + 2*Survivor
    年老代:OldGen
    在1.8中Perm区取消,使用Metaspace(元数据空间)进行替换。
    Metaspace使用的内存空间不是虚拟机内部,不属于堆内存,而是本地内存空间,这是与1.7最大的区别所在。
    在这里插入图片描述
    3.3 为什么要弃用永久区
    官网给出了解释:http://openjdk.java.net/jeps/122
    This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation. 移除永久代是为融合HotSpot JVM与 JRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。
    3.4 jstat命令查看堆内存
    jstat可以查看堆内存各部分使用量以及类加载情况。
    jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
  • jstat -class < pid >
    类加载统计
    在这里插入图片描述Loaded:加载class的数量
    Bytes:所占用空间大小
    Unloaded:未加载数量
    Bytes:未加载占用空间
    Time:时间
  • jstat -compiler < pid >
    编译统计在这里插入图片描述
    Compiled:编译数量。
    Failed:失败数量
    Invalid:不可用数量
    Time:时间
    FailedType:失败类型
    FailedMethod:失败的方法
  • jstat -gc < pid >
    指定打印的间隔和次数,每1秒中打印一次,共打印5次
    在这里插入图片描述
    S0C:第一个Survivor区的大小(KB)
    S1C:第二个Survivor区的大小(KB)
    S0U:第一个Survivor区的使用大小(KB)
    S1U:第二个Survivor区的使用大小(KB)
    EC:Eden区的大小(KB)
    EU:Eden区的使用大小(KB)
    OC:Old区大小(KB)
    OU:Old使用大小(KB)
    MC:方法区大小(KB)
    MU:方法区使用大小(KB) CCSC:压缩类空间大小(KB) CCSU:压缩类空间使用大小(KB) YGC:年轻代垃圾回收次数
    YGCT:年轻代垃圾回收消耗时间
    FGC:老年代垃圾回收次数
    FGCT:老年代垃圾回收消耗时间
    GCT:垃圾回收消耗总时间

4、jmap使用及内存溢出分析

4.1 查看内存使用情况
jmao -heap < pid >
在这里插入图片描述
在这里插入图片描述
4.2 查看内存中数量和大小
查看所有对象,包括活跃和非活跃的
jmap -histo < pid > | more
查看活跃对象
jmap -histo:live < pid > | more
4.3 将内存使用情况dump到文件中
jmap -dump:format=b,file=dumpFileName < pid >
在这里插入图片描述
4.4 通过jhat对dump文件分析
使用jmap对内存dump的文件是二进制文件,可以借助jhat工具进行查看。
jhat -port < port > < file >
在这里插入图片描述
可以使用浏览器访问9999端口即可。
在这里插入图片描述
4.5 使用mat工具对dump文件进行分析
MAT(Memory Analyzer Tool),是一个基于Eclipse的内存分析工具,可以查找内存泄漏,分析内存对象,提供报表分析展示。这款工具不仅可以分析dump出来的内存文件还可以直接连接运行的服务器获取内存文件。
官网地址:https://www.eclipse.org/mat/
在这里插入图片描述

5. jstack的使用

jstack主要用于查看jvm线程情况。jstack可以将正在运行的jvm线程情况进行快照。
jstack < pid>
在这里插入图片描述
在这里插入图片描述
可以看到,程序中出现了一个死锁
5.1 线程的状态
在这里插入图片描述

  • 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  • 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  • 阻塞(BLOCKED)。
    当一条正在执行的线程请求某一资源失败时,就会进入阻塞态。
    而在Java中,阻塞态专指请求锁失败时进入的状态。
  • 等待(WAITING)
    当前线程中调用wait、join、park函数时,当前线程就会进入等待态。
    线程处于等待态表示它需要等待其他线程的指示才能继续运行。
    进入等待态的线程会释放CPU执行权,并释放资源(如:锁)
  • 超时等待(TIMED_WAITING)
    它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其他线程唤醒;
    进入该状态后释放CPU执行权 和 占有的资源。
    与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。
  • 终止(TERMINATED)
    表示该线程已经执行完毕。

6、VisualVM工具的使用

VisualVM能够监视线程、内存情况。在jdk的bin目录下。
内存信息
线程信息
Dump堆(本地进程)
Dump线程(本地进程)
打开堆Dump。堆Dump可以用jmap来生成。
打开线程Dump
生成应用快照(包含内存信息、线程信息等等)
性能分析。CPU分析(各个方法调用时间,检查哪些方法耗时多),内存分析(各类对象占用的内存,检查哪些类占用内存多)
……
6.1监视远程的jvm
JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。
如果要监视远程的tomcat,需要对远程tomcat进行JMX配置。
#在tomcat的bin目录下,修改catalina.sh,添加如下的参数 JAVA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 - Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
#这几个参数的意思是:
#-Dcom.sun.management.jmxremote :允许使用JMX远程管理
#-Dcom.sun.management.jmxremote.port=9999 :JMX远程连接端口
#-Dcom.sun.management.jmxremote.authenticate=false :不进行身份认证,任何用户都可以连接
#-Dcom.sun.management.jmxremote.ssl=false :不使用ssl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值