ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-05-03 15:02:24  阅读:200  来源: 互联网

标签:KB XX 线程 内存 jvm 参数 工具 优化


一、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

标签:KB,XX,线程,内存,jvm,参数,工具,优化
来源: https://blog.csdn.net/li210530/article/details/116371293

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有