程序员:为什么程序总是那么慢?时间都花到哪里去了?

面试官:若你写的 Java 程序,出现了性能问题,该怎么去排查呢?

工欲善其事必先利其器,为你呈上一箩筐性能优化工具,必有一款满足你,废话不多说,直奔主题。

1. hprof 工具

hprof 工具是通过织入监控代码,来对 Java 程序进行监控的一款工具。可以监控 Java 程序在运行时占用的 CPU,及统计堆内存使用等。

例如:每隔 10 毫秒采样 CPU 消耗信息,并把信息保存到 hprof.txt 文件中。

java -agentlib:hprof=cpu=times,interval=10,file=hprof.txt class

  

指令运行完,打开 hprof.txt 便很容易统计出哪些方法的运行耗时较长。

例如:输出 Java 应用程序中各个类所占用的内存百分比。

java -agentlib:hprof=heap=sites,file=hprof.txt class
备注:若未指定 file=hprof.txt,则默认会生成 java.hprof.txt 文件

  

打开输出的文件,效果如下。

例如:将 Java 应用程序的堆快照保存在文件 core.hprof 中,然后就可以使用 VisualVM 等工具来分析这个堆文件啦。

java -agentlib:hprof=heap=dump,format=b,file=core.hprof class

  

采用 VisualVM 工具打开 core.hprof 文件进行分析堆快照,效果如下。

2. JConsole 工具

JConsole 是 Java 自带的图形化性能监控工具,可以让你摆脱命令行排查问题的痛苦。通过它,会非常容易的监测 Java 程序的运行情况。

2.1. 连接要监控的 Java 程序

首先进入 JDK 安装之后的 bin 目录,若是配置过 Java 的环境变量,直接运行 JConsole 就行,效果如下。

若是要监控本地 Java 进程,直接选择列表中的名称进行连接即可。

若是要监控远程 Java 进程,需要在远程 Java 程序启动时,需要加上下面几句话。

# 远程服务器的ip地址
-Djava.rmi.server.hostname=127.0.0.1
# 指定jmx监听的端口
-Dcom.sun.management.jmxremote.port=8099
# 指定jmx监听的端口
-Dcom.sun.management.jmxremote.rmi.port=8099
# 是否开启ssl
-Dcom.sun.management.jmxremote.ssl=false
# 是否开启认证
-Dcom.sun.management.jmxremote.authenticate=false

  

若是在 IDEA 开发工具中进行验证,按照下图进行配置,跑程序就行。

若是命令行启动时,按照下述方式配置,启动就行。

java -cp . -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=8099 -Dcom.sun.management.jmxremote.rmi.port=8099  -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false className

  

启动远程 Java 程序,JConsole 输入远程服务 IP 和 端口,连接即可。

2.2. 监控 Java 程序概况

如图所示,JConosle 连接上要监控的 Java 程序后,可以很方便的查看堆内存使用量、线程数量、加载类的数量以及 CPU 的占用率。

2.3. 内存监控

如图所示,在 JConsole 提供的内存监控页面,不仅能看到堆内存的使用情况,而且能查看非堆区的内存使用情况等等。另外,还提供了让 Java 应用强制进行一次 GC 的功能。

2.4. 线程监控

如图所示,通过 JConsole 提供的线程页面,可以方便查看系统内的线程数量,以及程序中所有的线程,并且还能看到线程的栈信息。另外,该页面还提供了检测死锁的支持,那么就可以快速的帮我们定位死锁的问题啦。

2.5. 类加载情况

如图所示,JConsole 还能够显示类加载情况,包括已经装载的类数量,以及已经卸载的类数量。

2.6. VM 摘要

如图所示,JConsole 提供的 VM 概要页面,能够显示当前 Java 应用程序的基本信息,包括运行环境、系统线程信息、堆信息等等。

2.7. MBean 管理

通过 JConsole 提供的 MBean 页面,我们可以对应用中的 MBean 进行统一管理,鉴于之前在剖析 Resin 服务器源码的时候,我们多次用到过,本次不再铺开去说。

3. VisualVM 工具

Visual VM 是可以替代 jstat、jmap、jhat、jstack 命令的一款故障诊断和性能监控的可视化工具,甚至可以替代 JConsole,所以我们还是有必要进行了解一下。

3.1 连接要监控的 Java 程序

首先进入 JDK 安装的 bin 目录,运行 jvisualvm,启动起来后和 JConsole 一样,可以选择本地和远程进行连接,效果如下。

本次着重介绍一下这款工具能干啥,如何连接 Java 程序就不带着一起做实验啦,不过已把操作步骤帮你梳理好了,照着做就行啦。

3.2 概述

如图所示,通过 VisualVM 提供的概述功能页,可以很方便的查看 Java 程序的进程 ID、JVM 参数、系统属性等等信息。

3.3 监视

这块和 JConsole 很像,VisualVM 将 CPU 使用情况、堆使用情况、类加载信息以及线程都做了图形界面展示,可以很直观的进行监测。

3.4 线程监控

VisualVM 可以展示详细的线程信息,让线程信息一览无余,并且会自动进行死锁检测,如果在当前程序中找到死锁,则会提示“检测到死锁”。另外,通过线程 Dump可以导出当前所有线程的堆栈信息。

3.5 抽样器

Visual VM 提供 CPU 和内存两个抽样器。通过 CPU 抽样器,可以帮助我们快速找到程序中占用 CPU 时间最长的方法;通过内存抽样器,可以帮助我们查看当前程序的堆信息。

CPU抽样器效果图:

内存抽样器效果图:

3.6 Profiler

Profiler 的功能和抽样器其实差不多,只不过抽样器是抽样进行检测,而 Profiler 是全面进行检测。

点击 CPU 按钮,效果如上图所示,则开启一个 CPU 性能分析会话,等 VisualVM 收集和统计完相关性能数据信息,将会显示在性能分析结果。

若点击内存按钮,则开启一个内存分析会话,等 VisualVM 收集和统计完相关性能数据信息,将会显示在性能分析结果,效果如上图所示。

3.7 快照

VisualVM 很多地方,都提供了快照功能,可以让我们保存某一个时刻应用程序的堆信息、线程堆栈等等保存成快照,以便性能优化后进行对比、分析使用。

3.8 插件

VisualVM 还可以通过安装插件,来实现更多可能性。

4. 最后

程序员编码那是本能,但是若能更好的解决生产问题,则会彰显个人才能。

工具一箩筐,你也别嫌多,因为总有一款适合你。但是工具说再多,若不进行实践,一切皆枉然,纸上得来终觉浅,只有实践才是硬道理!

有关 Java 性能分析工具,本次就分享就到这里,希望大家能够喜欢,下次我们将结合案例进行实践,敬请期待。

参考资料:《Java 程序性能优化》

 

Java 程序该怎么优化?(工具篇)的更多相关文章

  1. java.awt包提供了基本的java程序的GUI设计工具

    java.awt包提供了基本的java程序的GUI设计工具.主要包括下述三个概念: 组件--Component 容器--Container 布局管理器--LayoutManager package T ...

  2. Java程序员拥有这些工具,还怕干不出好活

    老话说,工欲善其事,必先利其器. 那么,作为编程人员,你都用过哪些“兵器”呢?你的”兵器“够”锋利”吗? 近期,有很多新朋友问,都有什么画流程图的工具,给推荐推荐? 索性,就静下来,好好梳理一下,从事 ...

  3. Java 程序该怎么优化?(技巧篇)

    搬砖者:为什么程序总是那么慢?它现在到底在干什么?时间都花到哪里去了? 面试官:简单谈谈 Java 程序性能优化? 1. 字符串处理优化,乃优化之源. 研发过程中,String 的 API 用的应该是 ...

  4. Java 程序该怎么优化?(实战篇)

    面试官:出现了性能问题,该怎么去排查呢? 程序猿:接口响应那么慢,时间都花到哪里去了? 运维喵:为什么你的应用跑着跑着,CPU 就接近 100%? 分享一些真实生产问题排查故事,看看能否涨姿势,能否 ...

  5. Java 程序该怎么优化?(命令篇)

    灵魂拷问,JDK 提供的命令,除了 java.javac,你还用过哪些命令呢? 灵魂再拷问,若你写的 Java 程序,出现了性能问题,该怎么去排查呢? Java 作为编程语言中的战斗机,JDK 默认已 ...

  6. JAVA程序员常用开发工具

    1.JDK (Java Development Kit)Java开发工具集 SUN的Java不仅提了一个丰富的语言和运行环境,而且还提了一个免费的Java开发工具集(JDK).开发人员和最终用户可以利 ...

  7. java程序员的NodeJS初识篇

    摘要 作为一个一直用java来写后端的程序员用NodeJS来写后台,实在不是很爽.这里记下这两个月的NodeJS学习所遇之坑,与java转NodeJS的同仁共勉.学习时间不长,若有理解错误,望指正. ...

  8. android 性能优化-工具篇

    一.Traceview 使用TraceView主要有两种方式: 1.直接打开DDMS,选择一个进程,然后按上面的“Start Method Profiling”按钮,等红色小点变成黑色以后就表示Tra ...

  9. (转)Android性能优化——工具篇

    Android性能优化是Android开发中经常遇见的一个问题,接下来将对Android性能优化方面的知识点做一个简单的梳理和总结,将从工具和代码两方面进行梳理.所谓工欲善其事必先利其器,本文首先来看 ...

随机推荐

  1. 浅谈Spring框架

    一.Spring简介 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构, 分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集 ...

  2. 【Android】四大组件归纳总结

    随着学习持续更新 四大组件均可使用android:process="name"在Manifest中声明成独立进程 Activity 生命周期 4种启动模式 Android使用回退栈 ...

  3. main.c(53): error: #268: declaration may not appear after executable statement in block

    这个问题是在编译STM32的程序时遇到的,这个错误的原因是对于变量的声明不能放在可执行语句后面,必须在主函数开头声明变量.在程序中声明一个变量时,需要在可执行语句之前声明,否则会出现以上错误.

  4. Postgresql实战经验之alter table 开小差了

    Postgresql实战经验之alter table 开小差了 今天需要将一张有数据的表中一个字段varchar 类型转换为timestamp类型,但是pg的alter table 语句却开小差,出现 ...

  5. Spring框架——IOC 自动装载

    IOC自动装载有两种形式 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  6. 解决Requires: libc.so.6(GLIBC_2.14)(64bit)错误解决方法

    glibc简介: glibc是GNU发布的libc库,即c运行库.glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc.glibc除了封装linux操作系统所提供的系统服 ...

  7. dvwa学习之七:SQL Injection

    1.Low级别 核心代码: <?php if( isset( $_REQUEST[ 'Submit' ] ) ) { // Get input $id = $_REQUEST[ 'id' ]; ...

  8. Contest 153

    2019-09-14 23:16:25 总体感受:节奏尚可,难度尚可.然而还是卡在了最后一题,完全没有想到使用dp. 注意点: 1)Contest的最后一题往往是DP,Graph,这个敏感度需要提高: ...

  9. Unity 游戏框架搭建 2019 (十三~十五) 接下来要学什么?& 第九个示例

    在之前的两篇中,我们使用 public 静态方法对之前的内容进行了一个抽取,有了 public 静态方法这个工具,我们的学习行为也发生了一点变化. 在没使用 public 关键字之前呢,每一个示例仅仅 ...

  10. 蓝桥杯——一步之遥,扩展gcd的应用

    1. 一步之遥 [问题描述]从昏迷中醒来,小明发现自己被关在X星球的废矿车里.矿车停在平直的废弃的轨道上.他的面前是两个按钮,分别写着“F”和“B”. 小明突然记起来,这两个按钮可以控制矿车在轨道上前 ...