千家信息网

怎样进行JVM性能监控和调优

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这期内容当中小编将会给大家带来有关怎样进行JVM性能监控和调优,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。JVM调优是Java中比较重要的知识点,尤其是分析JVM
千家信息网最后更新 2026年11月02日怎样进行JVM性能监控和调优

这期内容当中小编将会给大家带来有关怎样进行JVM性能监控和调优,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

JVM调优是Java中比较重要的知识点,尤其是分析JVM和监控JVM运行状态。

1. JVM性能监控

1、定位系统问题

  • 依据

    • GC日志

    • 堆转储快照(heapdump/hprof文件)

    • 线程快照(threaddump/javacore文件)

    • 运行日志

    • 异常堆栈

  • 分析依据的工具

    • jps:显示指定系统内的所有JVM进程

    • jstat:收集JVM各方面的运行数据

    • jinfo:显示JVM配置信息

    • jmap:形成堆转储快照(heapdump文件)

    • jhat:分析heapdump文件

    • jstack:显示JVM的线程快照

    • jconsole

    • visualVM

说明:后边两种是具有图形化界面的。

2、jps(是其他所有命令的基础)

作用:列出所有的JVM虚拟机进程。

格式:jps -l

3、jstat(是没有GUI界面的情况下,在运行期定位JVM性能问题的首选)

作用:查看gc数据和类加载卸载数据

格式:jstat option PID interval count

意义:每隔interval毫秒做一次option,一共做count次

说明:加载了3683个类,总共占有4355.3字节;卸载了0个类,卸载的类的字节数为0,类的加载与卸载共花销3.16秒

更多的jstat的使用,参看http://my.oschina.net/skyline520/blog/304805

4、jinfo

作用:查看和运行期修改JVM的配置参数

格式:jinfo -flag parameter PID

说明:修改3732进程下的MaxTenuringThreshold参数值,但是windows下失败。

5、jmap

作用:生成堆转储快照和查看最占内存的元素,用于分析内存泄露问题

格式(生成堆转储快照):jmap -dump:format=b,file=文件名 PID

说明:结果自己去看,太多了

6、jhat

作用:分析堆转储快照(与jmap配合)

格式:jhat 文件名

注意:该工具是万不得已才用的。

推出命令使用"ctrl+c"

7、jstack

作用:生成线程快照,定位线程长时间卡顿的原因(线程间死锁、死循环、请求外部资源导致的长时间等待)

格式:jstack -l PID

说明:查看3732进程中的所有线程的堆栈信息

《深入理解Java虚拟机》的作者提供了一个工具jsp页面,使得我们可以在程序运行时,随时运行该jsp页面,来查看线程堆栈信息,代码如下:

1 <%@ page language="java">注意:代码中我注释掉一段,是因为想也查出当前线程的堆栈信息,作者并没有这个注释。 总结:JVM性能相关的6个常用的JDK命令jps:查询JVM中的所有进程,找出将要操作的PID,是所有命令的基础jstat:查看相应JVM进程的gc、类加载卸载信息,是没有GUI界面查看JVM运行数据的首选jinfo:查看和在运行期动态修改JVM配置参数jmap:生成堆转储快照和比较占内存的对象jhat:配合jmap分析堆转储日志,除非没有其他工具可做这个事儿,否则就不用该工具jstack:生成线程快照,定位线程长时间卡顿的原因(线程间死锁、死循环、请求外部资源导致的长时间等待)输出gc信息到控制台-XX:+PrintGCDetails:输出GC的详细信息-XX:+PrintGCTimeStamps:输出GC的时间信息-XX:+PrintGCApplicatonStoppedTime:GC造成的应用暂停的时间输出gc信息到文件以上三个参数在这里依旧适用-Xloggc:文件路径/gc.log:输出到文件   图形化的JVM性能监控 1、图像化的故障处理工具JconsolevisualVM2、Jconsole进入"E:\Java\jdk1.6\bin",双击"jconsole.exe",弹出如下框:说明:这里列出了所有的JVM进程,一个Jconsole进程,一个eclipse(PID:4684),这相当于jps命令。选中其中一个PID,假设选中了eclipse,双击,出现下图:(注:之后的各个叶签,都是每4秒刷新一次)"内存":相当于jstat -gc,在上图中的详细信息部分,该部分对应的信息就是头部图表部分所写的参数(这里是"整个堆"的情况),同时对应的也是右下角部分柱状图所选中的柱子(这里是"堆"),对于"非堆"指的就是"方法区"(或者称为"永久代")。当然,这里也可以选择时间范围来查看相应的信息。"类":相当于jstat -class,列出了装载类和卸载类的相关信息。"线程":相当于jstack,折线图显示了线程数目的变化情况,包括峰值线程数量、活动线程数量;左下角展示了所有线程名称。双击相应的线程名称"VM摘要":相当于jinfo最后,测试一下线程死锁的现象。代码如下: View Code执行main()方法,之后去查看"线程"标签,点击"检测死锁",如下:发现线程Thread-95和Thread-106死锁(彼此拥有对方想要的锁)分析:1)Integer缓存机制Integer.valueOf(int xxx),该方法为了减少对象的创建,节省内存,会将xxx转化成的Integer对象缓存起来,之后只要是相同的xxx,那么这个方法都会直接从缓存中取出对象来。假设代码中的Integer.valueOf(1)生成的对象是java.lang.Integer@987197,而Integer.valueOf(2)生成的对象是java.lang.Integer@15e293a,那么之后无论调用多少次Integer.valueOf(1),也无论是哪一个线程去调用该方法,返回的都只是同一个对象java.lang.Integer@987197。也就是说上边的这段代码中的Integer.valueOf(i)只会生成两个不同的对象,就是java.lang.Integer@987197和java.lang.Integer@15e293a,而这两个对象也就是我们的锁对象。2)死锁发生的时机假设线程"Thread-95"执行到其第一个synchronized块中时(假设刚刚获取了锁对象java.lang.Integer@987197),这时候CPU时间片切换给了线程"Thread-106",而"Thread-106"执行其第一个synchronized块(获取了锁对象java.lang.Integer@15e293a),之后"Thread-106"要执行第二个synchronized块儿来获取锁对象java.lang.Integer@987197,这时候就获取不到了,因为这个锁对象正被"Thread-95"所持有,于是"Thread-106"就阻塞在java.lang.Integer@987197这个锁对象上,这时,假设CPU时间片又切换给了"Thread-95",该线程要执行第二个synchronized块来获取java.lang.Integer@15e293a,就获取不到了,因为该锁对象已被"Thread-106"所持有3)结果"Thread-95"持有锁对象java.lang.Integer@987197,阻塞在锁对象java.lang.Integer@15e293a;"Thread-106"持有锁对象java.lang.Integer@15e293a,阻塞在锁对象java.lang.Integer@987197 3、visualVM是一块更加全面的GUI监视工具,包含很多插件(需要自己下载),具体的见《深入理解Java虚拟机(第二版)》  JVM调优 1、JVM的调优主要是内存的调优,主要调两个方面:各个代的大小垃圾收集器选择2、各个代的大小常用的调节参数-Xmx-Xms-Xmn-XX:SurvivorRatio-XX:MaxTenuringThreshold-XX:PermSize-XX:MaxPermSize原则在实际开发中,前台不要使用jsp,使用velocity等模板引擎技术不要引入无关的jar-XX:SurvivorRatio过大:对象在年轻代的存活时间变长,可能在年轻代就被回收掉而不必进入年老代,但是相应的复制的时候survivor区就会被占用更多的空间。-XX:SurvivorRatio过大:对象在年轻代的存活时间变短,可能会早早进入年老代而失去在年轻代被回收的机会,但是相应的复制的时候survivor区也就有更多内存了,这样可能会避免部分大对象直接进入年老代-XX:SurvivorRatio过大:Eden变大,Survivor变小,minor GC可能减少,但是由于suvivor减小了,所以如果minor GC存活下来的对象大于suvivor,则会直接进入年老代-XX:SurvivorRatio过小:Eden变小,Survivor变大,minor GC可能增多,但是由于suvivor变大了,能够存储更多存活下来的对象,进入年老代的对象可能会减少 调节时机:minor GC太频繁-Xmn过小:minor GC太频繁;小对象可能也会直接进入年老代,提前导致Full GC-Xmn过大:年轻代大了,minor GC的时间变长了;年老代变小了,Full GC会频繁调节策略:若-Xmx可调大,则调大,且保持-Xmn==-Xmx/4~-Xmx/3;若-Xmx不可调大,在保持-Xmn==-Xmx/4~-Xmx/3的范围内增大-Xmn,若-Xmn也不可调了,则试着调大-XX:SurvivorRatio来看看情况-Xmx==-Xms:防止堆内存频繁进行调整,调整的时机见《第一章 JVM内存结构》-Xmn:通常设为-Xmx/4(这是我在企业中实习时的设置方式,系统运行正常、平稳、速度也快),林昊推荐的是-Xmx/3,所以-Xmn==-Xmx/4~-Xmx/3-XX:SurvivorRatio:默认8-XX:MaxTenuringThreshold:默认为15-XX:MaxPermSize==-XX:PermSize3、垃圾收集器选择企业中最常用的两个组合:(这里由于大部分大型企业用的还是JDK1.6,所以G1不说)关于下边两组垃圾收集器的详细原理见:第五章 JVM垃圾收集器(1)Parallel Scavenge/Parallel Old注重吞吐量(吞吐量越大,说明CPU利用率越高)主要用于处理很多的CPU计算任务而用户交互任务较少的情况也用于让JVM自动调优而我们袖手旁观的情况(-XX:+UseParallelOldGC,-XX:GCTimeRatio,-Xmx,-XX:+UseAdaptiveSizePolicy)-XX:+UseParallelOldGC:指定使用该组合ParNew/CMS注重STW的缩短(该时间越短,用户体验越好,而且会减少部分请求的请求超时问题)-XX:+UseConcMarkSweepGC:指定使用该组合-XX:CMSInitiatingOccupancyFraction:来指定当年老代空间满了多少后(百分比)进行垃圾回收关于上边两种组合的说明一般而言,在企业中,机器的CPU数量都比较多,且CPU的计算能力也不会成为瓶颈,所以对于CMS的并发标记与并发清除阶段,会占用CPU资源的问题,其实不是大事儿;而对于Parallel的注重吞吐量的问题也就不是什么大事儿了,毕竟CPU是强大的所以,ParNew/CMS是首选(在G1不能用的情况下),Parallel Scavenge/Parallel Old只在想让JVM自动管理内存的情况下使用注意:在实际调优过程中,可以使用jstat、jconsole、visualVM或GC日志的检测数据来调,具体的示例见《深入理解java虚拟机(第二版)》p142对eclipse运行速度的调优。关于GC日志的参数含义与每一种垃圾收集器的GC日志的格式,查看《深入理解Java虚拟机(第二版)》的P89和《深入分析java web技术内幕(修订版)》的P224

上述就是小编为大家分享的怎样进行JVM性能监控和调优了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

对象 线程 信息 内存 快照 分析 文件 时间 情况 进程 生成 运行 参数 工具 格式 性能 作用 垃圾 日志 问题 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网最新的科技 互联网科技公司电话 南京欣网互联网科技 友谊互联网络科技 青岛中康互联网医疗科技有限公司 深圳前海聚择互联网科技有限公司 互联网科技热点资讯 创业天下互联网科技有限公司 互联网时代科技改变生活 洛阳昕诺飞互联网科技有限公司 深圳市罗太互联网科技有限公司 科技大学互联网 互联网营销推广黑科技 互联网科技包装股 广州梦谷互联网科技有限公司领导 互联网高科技行业有哪些企业 好易买互联网科技 众联互联网络科技 科技互联网专业工作会议发言稿 山东蛋芒互联网科技有限公司 科技股互联网 奇酷互联网络科技公司 互联网科技宣传片 华脉科技工业互联网产品 苏州五指互联网络科技有限 赶超互联网科技 微信多开 沐思想互联网科技有限公司 小米互联网科技园入驻 盐城市攀科互联网科技有限公司 山东蛋芒互联网科技有限公司
0