GMTC全球大前端技术大会(北京站)门票9折特惠截至本周五,点击立减¥480 了解详情
写点什么

Java 性能调优工程的几点建议

2016 年 10 月 09 日

2016 年 8 月,由极客邦、InfoQ 和听云联合主办 APMCon 2016 中国应用性能管理大会上,Java 性能调优专家 Monica Beckwith 进行了《Java 性能调优必读守则》(原题目:Java Performance Engineer’s Survival Guide)的演讲。演讲中,Monica 给出关于 Java 调优最佳实践的个人建议:怎样设定需要调优的性能要求、需要对哪些指标进行分析、目标设定后又怎样具体地开展调优。

Monica Beckwith 专注于企业级应用中 Java 虚拟机和垃圾收集器的优化,发表过多篇垃圾收集器和 Java 内存模型方面的文章。她之前就职于 Oracle,带领 G1 垃圾收集器性能团队,目前是一位独立咨询师。在 Monica 演讲之后,InfoQ 又对她进行了专访。

性能调优前的准备工作

Monica 认为性能优化工程由两部分组成:性能需求分析及规划、性能结果分析。两者构成闭环,使得性能得到不断的提升。

一、性能需求分析及规划

在决定性能需求的时候,工程师们首先要问自己三个问题:

  1. 哪些会让用户开心?
  2. 哪些会让用户懊恼?
  3. 目前存在的问题需要被关注并解决吗?

接下来,需要站在用户的角度去思考 QoS;将 QoS 标准量化为可测量的指标,即 SLA 服务等级协议;然后对 SLA 性能指标进行定义、梳理并排列优先级(吞吐量、响应时间、容量、请求足迹、CPU 使用率等)。

  • 吞吐量 / 率:
    目标—是否可以比设定的吞吐量低?如果可以,这种状态可以持续多久?最低可以低到多少?
    测量—怎样测量?(事务数 / 秒、消息数 / 秒或者两种方式)哪里测量?(客户端、服务器端或者浏览器端)
  • 响应时间:
    目标—是否可以超出设定的响应时长?如果可以,这种状态可以持续多久?最长可以达到多久?
    测试—怎样测量?(取 99% 响应的时间计算均值、只统计某一段响应时间(5-9 秒)、最差的情况或者全部)哪里测量?(客户端、服务器端或者整个环路)
  • 容量管理:
    可以接受的容量是多少?如果某个系统过载怎么办(负载均衡出现问题)?怎样测量容量?一个系统和所有系统能承受的最大容量是多少?可以承受多久?需要监测哪些指标?

二、性能结果分析

关于性能结果分析,这里只讨论 Java 的性能分析。分析哪些因素会影响到终端用户体验,无法达到预期的 QoS;跟踪监测性能指标。下图是一个分层情况图:

  • 应用层生态系统:应用服务、应用服务器、数据库、生态系统中其他服务
  • JRE 层:类加载情况、JIT 编译情况、垃圾回收情况、线程情况
  • 操作系统层:系统 / 内核状态、锁状态、线程状态
  • 硬件层:内存带宽 / 内存吞吐量 / 内存占用、CPU/ 内核的使用、CPU 缓存效率 / 使用 / 级别、处理器结构、IO 状态

性能调优的执行

两种实现模式

Monica 提出了两种实现方式:自上而下、自下而上。采用哪一种要看你想要实现什么。

如果想从应用层面入手进行改进的话,且你是一个应用程序工程师,具备修改代码的能力,可以采用自上而下的方式。

如果想从平台层面入手进行改进的话,可采用自下而上的方式。首先你要明确平台的哪个模块是需要改进的;其次列出相关的应用、进行工作量的评估;然后再寻找恰当的工具。

四个步骤

不论哪一种方向,均可以分为四步:第一步监控、第二步归纳、第三步分析、第四步调优和应用。

通常而言,关心的指标有以下几个。
CPU:CPU 状态、内核状态、缓存命中和没有命中的次数、分支预测、流水线、条件转移、load-store 的工作模式等
内存:内存使用、内存、带宽、读写状态、读操作的最大带宽、写操作的最大带宽、最大容量、与结构相关的。
JVM/GC:收集与变化相关的信息、收集一般或者并发的 GC 各个阶段的信息、并发工作队列和工作状态、内部队列或缓存等。

  • 监控
    首先是从监控环节做起。
    监控方式分为三种:主动(报警设定)、被动(网络分流器)、离线(日志抓取)。
    可以选用的工具有三类:
    第三方——VisualVM、Java Flight Recorder
    JVM 自带命令——PrintCompilation、PrintGCDetails(+PrintGCDateStamps)、jmap-clstats、jcmd GC.class-stats
    操作系统自带——Linux 下面有 mpstat、sysstat – iostat、pidstat、prstat、vmstat、dash、CPU – Z、 cacti 等;Windows 下面有 Performance Monitor、Task Manager、Resource Monitor、CPU-Z、cacti 等
  • 归纳和分析
    接下来是归纳和分析环节。
    这个时候你已经有了所有需要的信息,你需要辨识出哪些地方需要提升,分析出哪些是潜在需要改进的问题。这个环节可以使用的开源工具有两类:
    第三方性能分析工具——Oracle Solaris Studio Performance Analyzer、perftools、PAPI、Code XL、 Dtrace、Oprofile、gprof、LTT
    Java 程序层面——Visual VM、Netbeans Profiler、JConsole
  • 调优
    最后一步调优。JVM/GC 的调优重点在于要选择对的堆、对的垃圾回收算法。首先正确划分对象的所属年代,然后只对长期存活的对象进行调优,每个虚拟机的所有 GC 工作线程(GC 的 stop-the-world 现象),同一个 VM 中多个 GC 线程来执行;看看压缩普通对象指针是否有效;大的堆也许需要使能 AlwaysPretouch 并且将 UseLargePages 设置为最佳大小。此外,在代码层面优化满足 SLA 目标,设置恰当的 ramp-up 和 ramp-down,对象的年代划分和保留策略(理解 LDS 文件的形成),确保测量正确。

对话 Monica

InfoQ: 在性能分析时,是否有必要收集所有的日志?

Monica: 当我们知道某处需要调优时,通常来讲用户们会给我发送过来产品环境中的日志,我们基于此复制环境,然后在这个复制的环境中进行测试和检查。我不建议在真实的环境中进行测试,因为生产环境需要保持稳定。什么情况下需要所有的日志呢?当我们确定知道某个问题的存在,比如内存泄露的问题,在这个时候就需要尽可能收集所有日志。

InfoQ: 能否分析下几种 GC 方式,并做以简单评价?

Monica: 垃圾回收是 Java 应用调优的核心。GC 不只有垃圾信息的收集、还有堆的管理分配信息;所有的分配都是类似的。一般而言,如果你有一个很小的空间可以给对象划分世代的话;hotspot JVM 中我建议在老年代对象上进行优化。因为年轻代占大多数,而且会死掉。老年代的回收算法中常见默认为垃圾标记 - 压缩算法。

CMS 垃圾回收器针对的是年老代的回收,从 root 对象开始标记存活对象。一旦空间中有不再存活的对象,所占用的资源就会被释放,并且更新到 free list 中;CMS 所做的就是要将年老代中所有应该归属于 free list 的都划分其中。

另外一种设计就是 G1。它将资源按区划分,有些区域共同构成年轻代,还有一些构成年老代,即同一个世代的所有区域并不一定是邻近的。每个区域最初都是任意的,需要通过声明才能定义为年轻代或者年老代。在收集时期,年老代并不是一定要全部参与。G1 在意的是收集有很多垃圾的区域。此外,G1 还会尝试调整年轻代的区间大小。

InfoQ: Java 中现在你最想改变的是什么?

Monica: Java 的非堆内存管理可能会在 JDK 9 或 JDK 10 中得到改善;此外检测内存泄露很困难,我认为有许多需要提升的地方。

InfoQ: 为了实现更好的性能,你认为 Java 软件开发工程师需要注意哪些事情?

Monica: 在编程的时候,要想到 Java GC 是怎样工作的。占用资源的并不是过期的对象,而是存活的对象;活的对象需要去维护。在编程的时候要明白对象的创立、保留策略还有垃圾回收器是怎样工作的。能考虑到这三点就很好了,你没有必要强制自己把每件事情都做对,只要整体可以协调妥帖就很好了。


感谢夏雪对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016 年 10 月 09 日 19:0014412
用户头像

发布了 58 篇内容, 共 38.4 次阅读, 收获喜欢 20 次。

关注

评论

发布
暂无评论
发现更多内容

Wireshark数据包分析学习笔记Day23

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

TcaplusDB X 秦时明月世界 |3月26日不删档测试正式开启

TcaplusDB

数据库 分布式 游戏 TcaplusDB

北漂三年!普通Java程序员跨城市面试经历和题库总结

Java王路飞

Java 程序员 架构 面试 分布式

HPE的通信技术集团将如何加速电信5G的普及和应用?

VoltDB

数据库 5G VoltDB 电信

LeetCode题解:剑指 Offer 49. 丑数,暴力法,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

视频云大赛|视频目标分割,下一个视频算法技术爆发点?

阿里云视频云

阿里云 算法 计算机视觉 音视频

java集合【12】——— ArrayList,LinkedList,Vector的相同点与区别是什么?

秦怀杂货店

Java 源码 集合

百位优质创作者签约计划|声网签约权益

InfoQ写作平台官方

活动专区 签约计划

常考面试题之css篇

小啵

融云2021 X-Meetup启航 探索高并发下的高质量实时通信架构设计

融云 RongCloud

python 国际化实践

walker12138

Python flask i18n

国内首个自主可控区块链技术发布!已在北京冷链追溯中显威

CECBC区块链专委会

区块链

PaddleWeekly | 飞桨开源项目每周推

百度大脑

量化交易系统开发;量化策略软件,马丁策略交易

13823153121

寻找被遗忘的勇气(二十六)

Changing Lin

3月日更

【OpenPyXL】对Excel单元格的操作

IT蜗壳-Tango

办公自动化 3月日更 IT蜗壳教学

国内唯一,阿里云挺进 Forrester 全球云数据仓库卓越表现者象限

阿里云大数据AI技术

云计算 大数据 阿里云 数据仓库 Forrester Wave

浅谈I/O多路复用

namelij

构建互联网医疗平台的Devops应用架构

读字节

DevOps 微服务 互联网架构 医疗 医疗中台

2020年京东161亿研发费用,钱怎么花的?

吴俊宇

投资 数字化 京东

身份验证会影响用户体验吗?

龙归科技

身份认证 用户体验 安全性

从低代码/无代码烂大街的吃瓜群众说起

李小腾

低代码 无代码开发

重磅官宣:Nacos2.0发布,性能提升10倍

阿里巴巴中间件

云计算 开源 nacos

百位优质创作者签约计划|InfoQ 签约权益

InfoQ写作平台官方

活动专区 签约计划

【得物技术】出价组DDD分层模型总结

得物技术

技术 总结 DDD 模型 出价

来云智技术论坛,带你认识 云智一体!

百度大脑

微软在比特币区块链上推出身份认证平台

CECBC区块链专委会

比特币

爱奇艺大数据生态的实时化建设

爱奇艺技术产品团队

大数据 实时数仓 数据流

I/O多路复用之EPOLL

namelij

中国唯一入选 Forrester 领导者象限,阿里云 Serverless 产品能力全球第一

阿里巴巴中间件

阿里云 Serverless Forrester Wave

安卓推送一体解决方案

融云 RongCloud

Java性能调优工程的几点建议-InfoQ