中国移动|Java性能优化的7个方向,不看你后悔

中国移动|Java性能优化的7个方向,不看你后悔

文章图片

中国移动|Java性能优化的7个方向,不看你后悔

文章图片

中国移动|Java性能优化的7个方向,不看你后悔

文章图片

中国移动|Java性能优化的7个方向,不看你后悔

文章图片

中国移动|Java性能优化的7个方向,不看你后悔

本文主要侧重于理论分析 , 我们从整体上看一下 Java 性能优化都有哪些可以遵循的规律 。 本文主讲理论 。 关于实践 , 后续的文章会用较多的案例来细化本文的知识点 , 适合反复思考和归纳 。
01

概述
性能优化根据优化的类别 , 分为业务优化和技术优化 。 业务优化产生的效果也是非常大的 , 但它属于产品和管理的范畴 。 同作为程序员 , 在平常工作中 , 我们面对的优化方式 , 主要是通过一系列的技术手段 , 来完成对既定的优化目标 。 这一系列的技术手段 , 我大体归纳为如图以下 7 类:

可以看到 , 优化方式集中在对计算资源和存储资源的规划上 。 优化方法中有多种用空间换时间的方式 , 但只照顾计算速度 , 而不考虑复杂性和空间问题 , 也是不可取的 。 我们要做的 , 就是在照顾性能的前提下 , 达到资源利用的最优状态 。
接下来 , 我简要介绍一下这7个优化方向 。 如果你感觉比较枯燥 , 那也没关系 , 我们本文的目的 , 就是让你的脑海里有一个总分的概念 , 以及对理论基础有一个整体的认识 。
02

复用优化
在写代码的时候 , 你会发现有很多重复的代码可以提取出来 , 做成公共的方法 。 这样 , 在下次用的时候 , 就不用再费劲写一遍了 。
这种思想就是复用 。 上面的描述是编码逻辑上的优化 , 对于数据存取来说 , 有同样的复用情况 。 无论是在生活中还是编码中 , 重复的事情一直在发生 , 如果没有复用 , 工作和生活就会比较累 。
在软件系统中 , 谈到数据复用 , 我们首先想到的就是缓冲和缓存 。 注意这两个词的区别 , 它们的意义是完全不同的 , 很多同学很容易搞混 , 在这里简单地介绍一下 。
缓冲(Buffer) , 常见于对数据的暂存 , 然后批量传输或者写入 。 多使用顺序方式 , 用来缓解不同设备之间频繁地、缓慢地随机写 , 缓冲主要针对的是写操作 。
缓存(Cache) , 常见于对已读取数据的复用 , 通过将它们缓存在相对高速的区域 , 缓存主要针对的是读操作 。
与之类似的 , 是对于对象的池化操作 , 比如数据库连接池、线程池等 , 在 Java 中使用得非常频繁 。 由于这些对象的创建和销毁成本都比较大 , 我们在使用之后 , 也会将这部分对象暂时存储 , 下次用的时候 , 就不用再走一遍耗时的初始化操作了 。
03

计算优化
并行执行
现在的 CPU 发展速度很快 , 绝大多数硬件 , 都是多核 。 要想加快某个任务的执行 , 最快最优的解决方式 , 就是让它并行执行 。 并行执行有以下三种模式 。
第一种模式是多机 , 采用负载均衡的方式 , 将流量或者大的计算拆分成多个部分 , 同时进行处理 。 比如 , Hadoop 通过 MapReduce 的方式 , 把任务打散 , 多机同时进行计算 。
第二种模式是采用多进程 。 比如 Nginx , 采用 NIO 编程模型 , Master 统一管理 Worker 进程 , 然后由 Worker 进程进行真正的请求代理 , 这也能很好地利用硬件的多个 CPU 。
第三种模式是使用多线程 , 这也是 Java 程序员接触最多的 。 比如 Netty , 采用 Reactor 编程模型 , 同样使用 NIO , 但它是基于线程的 。 Boss 线程用来接收请求 , 然后调度给相应的 Worker 线程进行真正的业务计算 。
像 Golang 这样的语言 , 有更加轻量级的协程(Coroutine) , 协程是一种比线程更加轻量级的存在 , 但目前在 Java 中还不太成熟 , 就不做过多介绍了 , 但本质上 , 它也是对于多核的应用 , 使得任务并行执行 。
变同步为异步
再一种对于计算的优化 , 就是变同步为异步 , 这通常涉及编程模型的改变 。 同步方式 , 请求会一直阻塞 , 直到有成功 , 或者失败结果的返回 。 虽然它的编程模型简单 , 但应对突发的、时间段倾斜的流量 , 问题就特别大 , 请求很容易失败 。