这本书的中文名叫做 《Java性能权威指南》, 翻译质量褒贬不一。
我读的是英文版,学习的过程中,顺便练习英语。
书名的完整描述为:
"Java Performance: The Definitive Guide by Scott Oaks (O’Reilly). Copyright 2014 Scott Oaks, 978-1-449-35845-7."
作者的源码仓库为: https://github.com/ScottOaks/JavaPerformanceTuning
Java性能相关的重要组件:
- JIT
- GC
- App
性能调优涉及的领域知识:
- 系统架构
- 程序开发
- 测试领域
- 运维领域
Java应用系统调优的切分:
- Java层面: 代码优化; API使用与最佳实践
- JVM层面: 配置参数调优: GC + Compiler
影响性能的因素:
- 算法优化
- JVM调优
- 系统瓶颈
这是一本致力于探索Java性能的科学和艺术性的书籍。
我们说性能是科学, 这一点也不为过。 性能领域涉及到很多的数值、分析和检测方法。 大部分性能调优工程师都具有一定的学术背景和科学素养, 通过科学的方法与手段, 来榨取最优性能。 至于艺术性, 性能优化真的一半是科学, 一半是艺术; 每一次优化都不是机械地照搬经验和结论, 而是需要灵感, 需要技巧的精彩艺术创作。
关于Java厂商:
- openJDK 的网站: https://openjdk.java.net/
- Oracle商业版本的JDK: 支持 JFR。
关于GC:
- JDK7推出了新的垃圾收集器: G1.
- 7u4之前的G1不属于GA版。
- JDK8中G1则比较稳定了。
- 每个厂商的GC配置参数都有不同, 新旧版本可能还有区别。
JVM扩展参数的格式:
- 布尔值类型:
-XX:+FlagName
与-XX:-FlagName
; 加号表示开启, 减号表示关闭. - 参数值类型:
-XX:FlagName=flagValue
; 参数值还可以分为字符串和数值。
关于默认参数;
- 大部分参数都有默认值.
- 有一些默认值是根据运行环境动态计算得出的。
- JDK8之前有 server 模式和 client 模式;
各种构件版本的JVM:
- product 版本, 一般是Oracle打包发行的版本。
- debug 版本;
- developer 版本, 支持更多的调优配置参数。
其他:
- Java和JVM之外,还有其他影响性能的因素。
- 默认行为;
- 代码级的算法和数据结构优化: 比如 二分、Hash优化、空间换时间/缓存。
编程的目的:
- 收入
- 乐趣
- 贡献
- 学习
代码与性能:
- 以代码量确定KPI
- 冗余/臃肿的低效代码: 类加载、编译成本、执行时间、对象分配与回收/GC成本、CPU高速缓存、code cache、内存资源。
- 硬件性能提升: 摩尔定律。
- 功能越多, 性能会越来越低, 因为需要消耗更多资源: 每次迭代降一点点,日积月累。
- 可以有小版本升级、以及性能优化,但是要考虑投入与产出。
过早优化:
- Donald Knuth 说的;
- 优化需要针对业务特征;
- 简洁直观就是优雅、可读性好: 同时兼顾性能优先.
- 收益与成本: 人力成本、沟通成本、项目周期.
- 不要故意去写太烂的代码。
- 不要教条主义, 看实际情况, 实事求是
外部因素:
- 数据库大部分时候是性能瓶颈.
- 分布式系统的瓶颈需要考虑整个链路。
- 负载: 请求数、并发数、数据量
优化原则:
-
- 绝大多数情况下, 先分析并优化代码逻辑;
-
- Occam’s Razor: 奥卡姆剃刀原理, "简单有效原理", "如无必要, 勿增实体", Entities should not be multiplied unnecessarily;
-
- 尽可能使用简单的算法;
小结:
- Java性能调优, 不仅仅是调优JVM;
- 各种系统组件, 都应该重视;
性能问题可能出现在任何地方, 包括:
- 软件
- 硬件
- 数据处理链路
方法的作用:
- 带领新手入门
- 检查清单
- 如何操作: 量化与确认
相关术语:
- IOPS: 每秒IO次数, 大部分情况下是指: 每秒读写磁盘的次数.
- 吞吐量: 指一定时间内完成的业务量, 比如事务,请求,数据传输等等.
- 响应时间: 从发出操作,到系统做出响应结果的时间.
- 延时/延迟: 等待的时间.
- 资源使用率: 比如内存、CPU、网络带宽、磁盘容量.
- 饱和度: 竞争资源需要排队的工作量.
- 瓶颈: 限制系统性能的直接组件/资源/原因.
- 负载: load, 工作负载, 也就是要干多少活; 就比如或者运输的货物量/需要执行的任务量/请求量.
- 缓存: 空间换时间, 受到的主要限制是成本。
- 压缩: CPU时间换空间。
性能测试模型:
- 干扰: 也就是其他的资源争用, 比如坏邻居。
- 排队: 也就是等待处理的队列/缓冲;
最受关注的性能指标:
- 响应时间: 客户方关注; 客户端响应时间 = 传输延时 + 服务端操作处理时间;
- 吞吐量: 服务方关注;
连接池:
- DNS查找时间,
- 创建TCP连接时的3次握手, 比如可以节省3/4的传输延迟。
- 数据传输时间, 这个是刚需, 只能优化代码或架构。
权衡
- 性能权衡三角
- 合格的语言生态: 具有完备的性能分析和调优工具。
- RCP协议: 当网络瓶颈不再成为限制, 压缩协议.
- 天之道,损有余而补不足。 用不紧缺的或者多余的资源来换取缺少的资源。
- 投资回报率: ROI
- 性能团队, 第三方监控
系统层级:
- 应用层: 应用栈/调用链/系统部署架构
- 数据库: 索引/IO
- 操作系统: 系统调用/调优/监控
- 文件系统:
- 存储系统: 容量、速度
指标维度:
- IOPS
- 吞吐量
- 延时
- 使用率: 忙碌/容量
- 饱和度: 超过处理能力
抽样分析(profiling)
缓存:
-
容量
-
密度, 工艺和技术限制
-
成本, 经济利益考虑
-
命中率/未命中率
-
热度: 冷、暖、热
-
最近最少使用: LRU
-
最近最多使用: MRU
预热(warm up):
- 性能测试
- 生产环境
- 关键路径
测试类型:
- 功能测试
- 性能测试
形式:
- 微基准测试: microbenchmark: 少量 代码
- 整体测试: macrobenchmark: 整个应用
- 部分测试: meso-benchmark: 模块级/流程级
- 回归测试: regression
- 单元测试: unit
- 模块测试: module-level testing
- 集成测试:
- 集群和扩展性:
- UA压测
业务代码: 主流程是最重要的部分, 是系统存在的原因和价值, . 效率工具: 提高效率, 节省人力, 可按业务量进行量化.
吞吐量:
- 子系统
- 业务处理单元
- 整个系统
- 瓶颈点
数据类型:
-
BigDecimal: 金额相关, 专业选择
-
double: