Java应用性能调优
性能诊断工具
性能诊断一种是针对已经确定有性能问题的系统和代码进行诊断,还有一种是对预上线系统提前性能测试,确定性能是否符合上线要求。本文主要针对前者,后者可以用各种性能压测工具(例如 JMeter)进行测试,不在本文讨论范围内。针对 Java 应用,性能诊断工具主要分为两层:OS 层面和 Java 应用层面(包括应用代码诊断和 GC 诊断)。
OS 诊断
OS 的诊断主要关注的是 CPU、Memory、I/O 三个方面。
CPU 诊断
对于 CPU 主要关注平均负载(Load Average),CPU 使用率,上下文切换次数(Context Switch)。
通过 top 命令可以查看系统平均负载和 CPU 使用率,图 2 为通过 top 命令查看某系统的状态。
平均负载有三个数字:63.66,58.39,57.18,分别表示过去 1 分钟、5 分钟、15 分钟机器的负载。按照经验,若数值小于 0.7*CPU 个数,则系统工作正常;若超过这个值,甚至达到 CPU 核数的四五倍,则系统的负载就明显偏高。图 2 中 15 分钟负载已经高达 57.18,1 分钟负载是 63.66(系统为 16 核),说明系统出现负载问题,且存在进一步升高趋势,需要定位具体原因了。
通过 vmstat 命令可以查看 CPU 的上下文切换次数,如图 3 所示:
图 3.vmstat 命令示例
for(Category c = this; c != null; c=c.parent) {
// Protected against simultaneous call to addAppender, removeAppender,…
synchronized(c) {
if (c.aai != null) {
write += c.aai.appendLoopAppenders(event);
}
…
}
}
Memory
从操作系统角度,内存关注应用进程是否足够,可以使用 free –m 命令查看内存的使用情况。通过 top 命令可以查看进程使用的虚拟内存 VIRT 和物理内存 RES,根据公式 VIRT = SWAP + RES 可以推算出具体应用使用的交换分区(Swap)情况,使用交换分区过大会影响 Java 应用性能,可以将 swappiness 值调到尽可能小。因为对于 Java 应用来说,占用太多交换分区可能会影响性能,毕竟磁盘性能比内存慢太多。
I/O
I/O 包括磁盘 I/O 和网络 I/O,一般情况下磁盘更容易出现 I/O 瓶颈。通过 iostat 可以查看磁盘的读写情况,通过 CPU 的 I/O wait 可以看出磁盘 I/O 是否正常。如果磁盘 I/O 一直处于很高的状态,说明磁盘太慢或故障,成为了性能瓶颈,需要进行应用优化或者磁盘更换。
除了常用的 top、 ps、vmstat、iostat 等命令,还有其他 Linux 工具可以诊断系统问题,如 mpstat、tcpdump、netstat、pidstat、sar 等。Brendan 总结列出了 Linux 不同设备类型的性能诊断工具,如图 4 所示,可供参考。
图 4.Linux 性能观测工具
Java 应用诊断工具
应用代码诊断
应用代码性能问题是相对好解决的一类性能问题。通过一些应用层面监控报警,如果确定有问题的功能和代码,直接通过代码就可以定位;或者通过 top+jstack,找出有问题的线程栈,定位到问题线程的代码上,也可以发现问题。对于更复杂,逻辑更多的代码段,通过 Stopwatch 打印性能日志往往也可以定位大多数应用代码性能问题。
常用的 Java 应用诊断包括线程、堆栈、GC 等方面的诊断。
jstack
jstack 命令通常配合 top 使用,通过 top -H -p pid 定位 Java 进程和线程,再利用 jstack -l pid 输出线程栈到控制台 .jstack -l pid >> xxxfile.dump到文件。由于线程栈是瞬态的,因此需要多次 dump,一般 3 次 dump,一般每次隔 5s 就行。将 top 定位的 Java 线程 pid 转成 16 进制,得到 Java 线程栈中的 nid,可以找到对应的问题线程栈。
图 5. 通过 top –H -p pid查看运行时间较长 Java 线程
如图 5 所示,其中的线程 24985 运行时间较长,可能存在问题,转成 16 进制后,通过 Java 线程栈找到对应线程 0x6199 的栈如下,从而定位问题点,如图 6 所示。
图 6.jstack 查看线程堆栈

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
VIM 配置及内核代码编译
1. 编译安装python 1.1 下载 python 源代码 $wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz $tar -zxvf Python-3.6.5.tgz; cd Python-3.6.5/ 1.2 安装 zlib 相关依赖 $sudo yum -y install zlib* 1.3 配置生成 makefile $./configure --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib" --enable-unicode=ucs4 --enable-optimizations 1.4 编译安装 python $make $sudo make alti
-
下一篇
单据类报表的制作
在银行、财务、销售等系统中,常常会看到这样一类报表,它们一般是从原来的手工报表年代沿袭而来,需要打印在固定大小的纸张上,有着固定的样式要求。具体的形式包括各种登记本册和票据等。 在没有报表工具之前,这类报表大部分使用Excel进行制作,费时费力还不易维护,每次都独自加班到很晚(一首凉凉送给自己)。今天,我要带一带新的节奏,展现一下神操作来制作这类单据报表。 这次我们拿公积金单据来进行具体操作演示。下图就是公积金管理中心为各单位提供的缴纳单据,一般要求单据的每一页上方都有单位信息,中间填写单位工作人员的具体公积金缴纳明细,最下面是合计和签章信息。一个手工年代的怀旧特点是,每页只显示7条数据,多了填到下一页,一页不够7行也要补上空行,而且要和纸质单据格式大小完全对应上: 单据报表效果图 好吧,为了按时下班,让我们用润乾报表赶紧开始吧: 首先,根据效果图绘制报表样式和框架,如下图: 单据报表框架图 【实用小技巧】因为单据类报表基本都需要打印在固定格式的单据上,也就是俗称的“套打”,所以在设计报表的时候就需要根据实际的单据来设计。具体做法是:用扫描仪扫描单据图片,然后把图片调好大小,设置为报表...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程