Java性能优化实战
知识记录者-vincent
这个作者很懒,什么都没留下…
展开
-
Java 性能优化之——性能优化的过程方法与求职面经总结
性能优化需要多方面权衡应用性能低,有很多方面的因素,比如业务需求层面、架构设计层面、硬件/软件层面等,这里主要是说的是软件层面,但也不要忘记性能优化还有其他手段先举个业务需求层面的例子。有一个报表业务,查询非常缓慢,有时候甚至会造成内存溢出。经过分析,发现是查询时间跨度范围太大造成的,由于业务上的限制,将时间跨度缩小至 1 个月之内之后,查询速度就快了很多 再举一个硬件层面的例子。有一个定时任务,可以算是 CPU 密集型的,每次都将 CPU 用得满满的。由于系统有架构上的硬伤,无法做到横向扩容。原创 2020-12-25 14:47:59 · 387 阅读 · 0 评论 -
Java 性能优化之——SpringBoot 服务性能优化
在开始对 SpringBoot 服务进行性能优化之前,需要做一些准备,把 SpringBoot 服务的一些数据暴露出来。比如,你的服务用到了缓存,就需要把缓存命中率这些数据进行收集;用到了数据库连接池,就需要把连接池的参数给暴露出来。这里采用的监控工具是 Prometheus,它是一个是时序数据库,能够存储我们的指标。SpringBoot 可以非常方便地接入到 Prometheus 中SpringBoot 如何开启监控?创建一个 SpringBoot 项目后,首先加入 maven 依赖.原创 2020-12-25 11:17:23 · 2312 阅读 · 5 评论 -
Java 性能优化之—— JVM 常见优化参数
现在大家用得最多的 Java 版本是 Java 8,如果你的公司比较保守,那么使用较多的垃圾回收器就是 CMS 。但 CMS 已经在 Java 14 中被正式废除,随着 ZGC 的诞生和 G1 的稳定,CMS 终将成为过去式,Java 9 之后,Java 版本已经进入了快速发布阶段,大约是每半年发布一次,Java 8 和 Java 11 是目前支持的 LTS 版本由于 JVM 一直处在变化之中,所以一些参数的配置并不总是有效的。有时候你加入一个参数,“感觉上”运行速度加快了,但通过 -XX:+Print原创 2020-12-24 17:17:51 · 1565 阅读 · 1 评论 -
Java 性能优化之—— JIT 如何影响 JVM 的性能
Java 虚拟机栈,其实是一个双层的栈,如下图所示,第一层就是针对 method 的栈帧,第二层是针对字节码指令的操作数栈栈帧的创建是需要耗费资源的,尤其是对于 Java 中常见的 getter、setter 方法来说,这些代码通常只有一行,每次都创建栈帧的话就太浪费了另外,Java 虚拟机栈对代码的执行,采用的是字节码解释的方式,考虑到下面这段代码,变量 a 声明之后,就再也不被使用,要是按照字节码指令解释执行的话,就要做很多无用功public class A{ int attr..原创 2020-12-24 16:35:21 · 685 阅读 · 1 评论 -
Java 性能优化之—— JVM 如何完成垃圾回收
JVM 内存区域划分如下图所示,内存区域划分主要包括堆、Java 虚拟机栈、程序计数器、本地方法栈、元空间和直接内存这五部分,将逐一介绍1.堆如图所示,JVM 中占用内存最大的区域,就是堆(Heap),我们平常编码创建的对象,大多数是在这上面分配的,也是垃圾回收器回收的主要目标区域2.Java 虚拟机栈JVM 的解释过程是基于栈的,程序的执行过程也就是入栈出栈的过程,这也是 Java 虚拟机栈这个名称的由来Java 虚拟机栈是和线程相关的。当你启动一个新的线程,Java 就会为原创 2020-12-24 16:05:28 · 171 阅读 · 0 评论 -
Java 性能优化之—— 常见 Java 代码优化法则
代码优化法则1.使用局部变量可避免在堆上分配由于堆资源是多线程共享的,是垃圾回收器工作的主要区域,过多的对象会造成 GC 压力。可以通过局部变量的方式,将变量在栈上分配。这种方式变量会随着方法执行的完毕而销毁,能够减轻 GC 的压力2.减少变量的作用范围注意变量的作用范围,尽量减少对象的创建。如下面的代码,变量 a 每次进入方法都会创建,可以将它移动到 if 语句内部public void test1(String str) { final int a = 100; i...原创 2020-12-24 14:50:39 · 631 阅读 · 0 评论 -
Java 性能优化之——从BIO 到 NIO,再到 AIO
Netty 的高性能架构,是基于一个网络编程设计模式 Reactor 进行设计的。现在,大多数与 I/O 相关的组件,都会使用 Reactor 模型,比如 Tomcat、Redis、Nginx 等,可见 Reactor 应用的广泛性。Reactor 是 NIO 的基础。为什么 NIO 的性能就能够比传统的阻塞 I/O 性能高呢?首先来看一下传统阻塞式 I/O 的一些特点阻塞 I/O 模型如上图,是典型的BIO 模型,每当有一个连接到来,经过协调器的处理,就开启一个对应的线程进行接管。如.原创 2020-12-24 11:19:01 · 545 阅读 · 3 评论 -
Java 性能优化之—— 乐观锁和无锁
Lock 是基于 AQS(AbstractQueuedSynchronizer)实现的,AQS 是用来构建 Lock 或其他同步组件的基础,它使用了一个 int 成员变量来表示state(同步状态),通过内置的 FIFO 队列,来完成资源获取线程的排队synchronized的方式加锁,会让线程在 BLOCKED 状态和 RUNNABLE 状态之间切换,在操作系统上,就会造成用户态和内核态的频繁切换,效率就比较低与 synchronized 的实现方式不同,AQS中很多数据结构的变化,都是依赖 CA原创 2020-12-24 09:49:09 · 376 阅读 · 0 评论 -
Java 性能优化之——多线程锁的优化
锁对性能的影响,是非常大的。因为对资源加锁以后,资源就被加锁的线程独占,其他的线程就只能排队等待这个锁,此时程序由并行执行,变相地成了顺序执行,执行速度自然就降低了下面是开启了 50 个线程,使用 ThreadLocal 和同步锁方式性能的一个对比Benchmark Mode Cnt Score Error UnitsSynchronizedNormalBenchmark.sync thrp...原创 2020-12-23 16:37:16 · 596 阅读 · 0 评论 -
Java 性能优化之—— 并行计算让代码“飞”起来
并行获取数据场景:有一个用户数据接口,要求在 50ms 内返回数据。它的调用逻辑非常复杂,打交道的接口也非常多,需要从 20 多个接口汇总数据。这些接口,最小的耗时也要 20ms,哪怕全部都是最优状态,算下来也需要 20*20 = 400ms如下图,解决的方式只有并行,通过多线程同时去获取计算结果,最后进行结果拼接但这种编程模型太复杂了,如果使用原始的线程 API,或者使用 wait、notify 等函数,代码的复杂度可以想象有多大。但幸运的是,现在 Java 中的大多数并发编程场景,都可以原创 2020-12-23 15:40:48 · 696 阅读 · 0 评论 -
Java 性能优化之—— 如何用设计模式优化性能
代码的结构对应用的整体性能,有着重要的影响。结构优秀的代码,可以避免很多潜在的性能问题,在代码的扩展性上也有巨大的作用;结构清晰、层次分明的代码,也有助于帮你找到系统的瓶颈点,进行专项优化设计模式就是对常用开发技巧进行的总结,它使得程序员之间交流问题,有了更专业、便捷的方式。I/O 模块使用的是装饰器模式,你就能很容易想到 I/O 模块的代码组织方式,事实上,大多数设计模式并不能增加程序的性能,它只是代码的一种组织方式如何找到动态代理慢逻辑的原因?Spring 广泛使用了代理模式,它使用 .原创 2020-12-23 11:42:58 · 518 阅读 · 0 评论 -
Java 性能优化之——大对象复用的目标和注意点
对于“大对象”的优化。“大对象”是一个泛化概念,它可能存放在 JVM 中,也可能正在网络上传输,也可能存在于数据库中为什么大对象会影响我们的应用性能呢? 第一,大对象占用的资源多,垃圾回收器要花一部分精力去对它进行回收; 第二,大对象在不同的设备之间交换,会耗费网络流量,以及昂贵的 I/O; 第三,对大对象的解析和处理操作是耗时的,对象职责不聚焦,就会承担额外的性能开销 结合缓存,以及对象的池化操作,加上对一些中间结果的保存,我们能够对大对象进行初步的提速,但这还远远原创 2020-12-23 11:01:47 · 3390 阅读 · 0 评论 -
Java 性能优化之——池化对象的应用场景
在我们平常的编码中,通常会将一些对象保存起来,这主要考虑的是对象的创建成本。比如像线程资源、数据库连接资源或者 TCP 连接等,这类对象的初始化通常要花费比较长的时间,如果频繁地申请和销毁,就会耗费大量的系统资源,造成不必要的性能损失。并且这些对象都有一个显著的特征,就是通过轻量级的重置工作,可以循环、重复地使用。这个时候,我们就可以使用一个虚拟的池子,将这些资源保存起来,当使用的时候,我们就从池子里快速获取一个即可公用池化包 Commons Pool 2.0首先来看一下 Java 中公用的池.原创 2020-12-23 09:35:59 · 1151 阅读 · 1 评论 -
Java 性能优化之——Redis 如何助力秒杀业务
什么叫分布式缓存呢?它其实是一种集中管理的思想。如果我们的服务有多个节点,堆内缓存在每个节点上都会有一份;而分布式缓存,所有的节点,共用一份缓存,既节约了空间,又减少了管理成本在分布式缓存领域,使用最多的就是 Redis。Redis支持非常丰富的数据类型,包括字符串(string)、列表(list)、集合(set)、有序集合(zset)、哈希表(hash)等常用的数据结构。当然,它也支持一些其他的比如位图(bitmap)一类的数据结构说到 Redis,就不得不提一下另外一个分布式缓存Memc..原创 2020-12-22 16:02:52 · 243 阅读 · 0 评论 -
Java 性能优化之——高并发系统的法宝,无处不在的缓存
和缓冲类似,缓存可能是软件中使用最多的优化技术了,比如:在最核心的 CPU 中,就存在着多级缓存;为了消除内存和存储之间的差异,各种类似 Redis 的缓存框架更是层出不穷缓存的优化效果是非常好的,它既可以让原本载入非常缓慢的页面,瞬间秒开,也能让本是压力山大的数据库,瞬间清闲下来缓存,本质上是为了协调两个速度差异非常大的组件,如下图所示,通过加入一个中间层,将常用的数据存放在相对高速的设备中在我们平常的应用开发中,根据缓存所处的物理位置,一般分为进程内缓存和进程外缓存,在进程内缓存上,原创 2020-12-22 13:57:30 · 303 阅读 · 0 评论 -
Java 性能优化之——缓冲区如何让代码加速
深入理解缓冲的本质缓冲(Buffer)通过对数据进行暂存,然后批量进行传输或者操作,多采用顺序方式,来缓解不同设备之间次数频繁但速度缓慢的随机读写你可以把缓冲区,想象成一个蓄水池。放水的水龙头一直开着,如果池子里有水,它就以恒定的速度流淌,不需要暂停;供水的水龙头速度却不确定,有时候会快一些,有时候会特别慢。它通过判断水池里水的状态,就可以自由控制进水的速度。或者再想象一下包饺子的过程,包馅的需要等着擀皮的。如果擀皮的每擀一个就交给包馅的,速度就会很慢;但如果中间放一个盆子,擀皮的只管往里扔,包馅的原创 2020-12-21 16:55:28 · 1251 阅读 · 0 评论 -
Java 性能优化实战——工具介绍
哪些资源,容易成为瓶颈?计算机各个组件之间的速度往往很不均衡,比如 CPU 和硬盘,比兔子和乌龟的速度差还大,那么按照木桶理论,可以说这个系统是存在着短板的。当系统存在短板时,就会对性能造成较大的负面影响,比如当 CPU 的负载特别高时,任务就会排队,不能及时执行。而其中,CPU、内存、I/O 这三个系统组件,又往往容易成为瓶颈CPU首先是计算机中最重要的计算组件中央处理器 CPU,围绕 CPU 一般我们可以通过 top 命令,来观测 CPU 的性能; 通过负载,评估 CPU 任务执行的原创 2020-12-21 15:01:03 · 700 阅读 · 0 评论 -
Java 性能优化实战——方法论
性能优化有哪些困扰?工作场景中遇到“性能优化”难题,往往只能靠盲猜和感觉,用临时性的补救措施去掩盖,看似解决了问题,但下次同样的问题又会发作,原因则是缺乏方法论、思路的指引,以及工具支持 能力修炼中,由于常年接触 CRUD,缺乏高并发这一实践环境,对“性能优化”只能通过理论知识进行想象,无法认识其在工作实战中的真实面目和实操过程 职场晋升中,只管功能开发,不了解组件设计原理,缺少深入地思考与总结,无法完成高并发、高性能系统设计这类高阶工作,难以在工作中大展拳脚,而有挑战的工作往往留给有准备的人原创 2020-12-18 14:08:32 · 683 阅读 · 0 评论