Java性能优化建议

应用层面

  1. 反射操作记得缓存method和field,最好能用方法句柄或者字节码增强替换掉
public class PerformanceOptimizationDemo {private static final Method METHOD;static {METHOD = "获取method";}}

更多细节见 Java反射性能详解

  1. 原生String的split和replaceAll请谨慎使用,StringTokenizer是个更好的选择,或者这里推荐org.apache.commons.lang3.StringUtils#replace(String, String, String)这个工具类
  2. 慎用String.intern,当字符串数量非常多时使用hashmap做缓存性能要好得多
  3. 放弃Random随机数请用ThreadLocalRandom
public static int getRandomNum() {// 性能略差return new Random().nextInt();// 性能更好的平替return ThreadLocalRandom.current().nextInt();
}
  1. 正确应用单例模式,逻辑类尽量使用单例,需注意处理线程安全问题,这里推荐静态工厂方式,其唯一的问题是较多的冗余代码,可使用插件解决
public class PerformanceOptimizationDemo {private PerformanceOptimizationDemo(){}private static class LazyHolder {private static final PerformanceOptimizationDemo INSTANCE = new PerformanceOptimizationDemo();}protected static PerformanceOptimizationDemo getInstance() {return PerformanceOptimizationDemo.LazyHolder.INSTANCE;}}
  1. 使用三方库如果是实例级的方法而非static的使用方法,查看api查看实例是否线程安全,线程安全时创建一个单例实例,而非在方法中每次都创建一个实例如ObjectMapper,此外对应各种FactoryContext要更严格地检查,频繁地创建Factory和Context可能会对内存造成较大的压力甚至导致Fullgc
private static final ObjectMapper DEFAULT_OBJECT_MAPPER = getObjectMapper();
  1. 递归调用层次比较深时但可以预见栈底时优化为循环(相当于手动实现尾递归转为循环)
  2. 合理使用多级缓存, 本地缓存->远程缓存(redis、etcd) ,做缓存时考虑好超时时间、淘汰策略、容量规划、最终一致性,这里推荐jetcache
@Override
@Cached(name = "user.", key = "#id", expire = 3600, cacheType = CacheType.REMOTE, postCondition = "result != null")
public UserInfo getData(Long id) {return Optional.ofNullable(userMapper.selectById(id)).map(user -> convert(user, UserInfo.class)).orElse(null);
}

9.接上一条,业务配置数据在初始化时直接加载到缓存和内存,优先从内存和缓存读取,没有再去读数据库并加载到内存和缓存中
10. Mq消息批处理
11. 数据库批处理(尽量不要在for循环里面进行数据库操作),注意jdbc参数rewriteBatchedStatementsallowMultiQueries要为true

private final UserMapper userMapper;public void batchInsert(List<UserDo> userList) {// 此种操作会占用较多的数据库连接且多次访问数据库rt会慢很多userList.forEach(user -> userMapper.insert(user));
}
  1. 数据库部分场景下有事务比没有事务要执行的更快,比如一些查询虽然是本身是无事务性的,但是多个小的查询放在一个事务中有利于复用连接避免了从连接池中获取连接的开销(没有连接池的话这个应用是存在一定问题的)
@Transactional(readOnly = true)
public void doSomething() {doQuery0();doQuery1();doQuery2();
}
  1. 巨型对象使用完手动赋值null(请一定确认是个巨型对象也不会再次复用)
  2. 业务允许的情况下使用cas+重试替换悲观锁
  3. 涉及大文件操作,使用nio技术优化写入(小文件可能适得其反),简单示例:
public static void writeToFile(String filePath, String content) throws IOException {try (FileOutputStream fos = new FileOutputStream(filePath);FileChannel channel = fos.getChannel()) {// 将内容转换为字节数组byte[] bytes = content.getBytes();// 创建ByteBufferByteBuffer buffer = ByteBuffer.allocate(bytes.length);buffer.put(bytes);// 将Buffer切换为读取模式buffer.flip();// 将数据写入到文件通道while (buffer.hasRemaining()) {channel.write(buffer);}}
}
  1. 开启多线程多个独立任务并发进行(谨慎使用, 多线程调试困难且使用不当会引发全局性的问题),一般而言多线程主要是实现rt的降低并不会实现资源利用率的提升
  2. 接上一条线程应当在线程池中运行,顺便贴一些使用线程池的注意点:
  • 线程池使用的注意点
    • ThreadLocal(登录信息上下文或其它的业务信息)丢失;
    • 合适的任务队列及其大小,过大会造成 oom ;
    • 全链路 id 丢失;
    • 合适的线程池策略和线程数(固定数目和不定数目);
    • 任务重启丢失(优雅退出);
  1. 大循环里面可以使用Thread.sleep(0) 让线程重新竞争,可以更充分的利用cpu资源(上下文切换也有开销),native方法执行以后就会插入一个safepoint,可以帮助gc
  2. 尝试r2dbc这种异步数据库连接框架(谨慎,需搭配一整套异步框架使用)
  3. 日志异步化, 异步输出日志不阻塞业务线程,资源允许的情况下引入类似kafka+ elk的日志系统,把日志的开销直接抽离业务系统
  4. 数据库连接预热,缓存预热及其它可预热的资源,在预热资源空闲率之间做权衡
  5. 连接数和线程数调整(数据库连接池、redis连接池、http连接池、tomcat线程数配置, dubbo处理线程数配置)等
  6. 使用aop切面功能时将aspectj相关jar包版本升级到1.9.0及以上,如果是根据注解切面RetentionPolicy应设置为RUNTIME

数据库层面

  1. 合理设计表结构冗余等要适当,要对数据量做合理的评估
  2. 分库分表:需考虑分库事务、读扩散等问题,对原有的join方式可能不兼容
    • 分库分表方式
      • 客户端分表
      • 使用数据库代理层
      • 使用分布式数据库
    • 分库分表策略
      • 按分片键水平分
      • 按时间(年/月/周/日)分
      • 其它自定义策略
  3. 合理加索引:是否有足够区分度?联合索引还是独立索引?是否唯一?索引容量。
  4. 索引性能和预期时刻想差较大时刻重建索引(该项慎重,小心锁表时间过长影响业务)
  5. 定期优化表消除空间碎片,可考虑业务低谷期重做一些表(需考虑表的大小预估时间),最好配合合理的数据归档

机器层面

  1. redis绑核
  2. jvm参数调优(该项做不好就是反向优化需慎重)
  3. 内核参数调整(文件打开数、线程限制、页大小等需慎重)

网络层面

  1. cdn优化寻址
  2. nginx配置优化(工作线程数等,nginx是一个多进程架构)
  3. tcp参数调优

性能优化没有银弹,所有的优化要以业务的诉求和业务量为基石,实践是检验真理的唯一标准。

原文地址: https://pebble-skateboard-d46.notion.site/Java-9e8e05c6bdcf4b64a24a9697d74e48ab?pvs=74

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/650654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低代码开发业务在AIGC时代的应用

随着人工智能和图形计算能力的快速发展&#xff0c;低代码开发平台在AIGC&#xff08;人工智能&#xff0c;物联网&#xff0c;大数据和云计算&#xff09;时代中扮演着至关重要的角色。本文将介绍低代码开发业务的概念和优势&#xff0c;探讨其在AIGC时代的应用及其对传统软件…

听力下降为什么会影响到言语感知?

一、听力障碍对阈值、听觉频率范围和分辨能力的影响 听力障碍使得听障者的听敏度降低&#xff0c;提高了阈值&#xff0c;不利于言语信号的接收。听障者听力阈值的变化在不同频率并不相同&#xff0c;一般而言&#xff0c;高频部分的听力损失往往大于低频部分&#xff0c;而言…

cuda编程学习

核函数 核函数是cuda编程关键通过创建.cu创建cudac程序文件&#xff0c;然后交给nvcc编译加上__global__前缀的函数由host端调用&#xff0c;__device修饰的函数为device函数&#xff0c;由设备调用__host修饰的函数为host函数&#xff0c;由设备调用host调用核函数的方式是fu…

fatal error:require():Failed opening required

今天部署网站遇到了个错误 fatal error:require():Failed opening required 这个错误经常遇到 大多是网站 是开启了 open_basedir 但今天这个错误很神奇 先说解决方法 1. 检测一下是不是真的 不存在这个文件 即使100%确定 也建议你再仔细看一下 这个文件存不存在 今天我遇…

Linux:利用匿名管道构建进程池

文章目录 进程池实现进程池创建信道和进程发送任务释放资源 进程池代码总结 本篇的主题是借助前面所学的基础管道实现一个进程池&#xff0c;那么在实现进程池前先了解进程池是什么&#xff0c;进程池有什么意义&#xff0c;进而对于进程池有一个基本的把握 进程池 给定一个进…

MySQL数据库备份的相关命令-运维面试常问

通过mysqldump命令备份某个数据库 使用如下格式的mysqldump命令来备份单个数据库&#xff1a; mysqldump -u [用户名] -p[密码] [数据库名] > [备份文件路径] [用户名]&#xff1a;是用于连接到MySQL服务器的用户名&#xff0c;通常拥有对指定数据库备份权限的用户。 [密…

学习笔记-李沐动手学深度学习(四)(12-13,权重衰退、L2正则化、Dropout)

总结 【trick】过拟合及正则化项参数的理解 实际数据都有噪音&#xff0c;一般有噪音后&#xff0c;模型实际学习到的权重w就会比 理论上w的最优解&#xff08;即没有噪音时&#xff09;大。&#xff08;QA中讲的&#xff09; 【好问题】 &#xff08;1&#xff09;不使用正…

svg 属性详解:填充与边框

svg 属性详解&#xff1a;填充与边框 1 颜色和透明度2 填充规则 fill-rule3 边框样式3.1 stroke-width3.2 stroke-linecap3.3 stroke-linejoin3.4 stroke-dasharray 1 颜色和透明度 图像都有颜色&#xff0c;svg 中可以使用属性 fill 和 stroke 来修改图形的颜色。fill 属性设置…

九州金榜|家庭教育中孩子厌学原因及解决办法

作为家长我们希望自己的孩子热爱学习&#xff0c;并取得优异成绩。但是&#xff0c;在现实中&#xff0c;孩子往往会出现厌学情绪&#xff0c;作为家长为此感到非常困扰。如何帮助孩子克服厌学情绪&#xff0c;九州金榜家庭教育将会带大家找出背后的原因&#xff0c;并寻找有效…

Tortoise-tts Better speech synthesis through scaling——TTS论文阅读

笔记地址&#xff1a;https://flowus.cn/share/a79f6286-b48f-42be-8425-2b5d0880c648 【FlowUs 息流】tortoise 论文地址&#xff1a; Better speech synthesis through scaling Abstract: 自回归变换器和DDPM&#xff1a;自回归变换器&#xff08;autoregressive transfo…

SpringSecurity(15)——OAuth2密码模式

工作流程 将用户和密码传过去&#xff0c;直接获取access_token&#xff0c;用户同意授权动作是在第三方应用上完成&#xff0c;而不是在认证服务器&#xff0c;第三方应用申请令牌时&#xff0c;直接带用户名和密码去向认证服务器申请令牌。这种方式认证服务器无法判断用户是…

网站服务器中毒或是被入侵该怎么办?

随着互联网的普及和发展&#xff0c;网站服务器已经成为了企业和个人存储数据、展示信息的重要平台。然而&#xff0c;网络安全问题也日益突出&#xff0c;其中网站服务器中毒或被入侵的事件时有发生。一旦发生这种情况&#xff0c;不仅会导致网站无法正常运行&#xff0c;还可…

阿里云负载均衡对接

1 、开通负载均衡产品 2 、ALB / NLB / CLB ALB&#xff1a; 应用型负载均衡 &#xff0c; 给定对应服务域名与当前实例DNS绑定之后即可使用 支持&#xff1a; HTTP/HTTPS/QUIC等应用层流量协议 NLB&#xff1a; 网络型负载均衡 支持&#xff1a; TCP / UDP / TCPSSL C…

浏览器——HTTP缓存机制与webpack打包优化

文章目录 概要强缓存定义开启 关闭强缓存协商缓存工作机制通过Last-Modified If-Modified-Since通过ETag If-None-Match 不使用缓存前端利用缓存机制&#xff0c;修改打包方案webpack 打包webpack 打包名称优化webpack 默认的hash 值webapck其他hash 类型配置webpack打包 web…

使用镜像源在 Jupyter Notebook中直接安装JupyterLab

具体步骤&#xff1a; 1.打开 Jupyter Notebook 首先确保你已经打开了 Jupyter Notebook&#xff0c;并且可以访问一个笔记本。 2.选择合适的镜像源 根据你的地理位置和网络状况&#xff0c;选择一个适合的镜像源。例如&#xff0c;如果你在中国&#xff0c;可以使用清华大…

STM32连接阿里云物联网平台

文章目录 引言一、STM32连接阿里云物联网平台思路二、ESP8266烧录固件三、使用AT指令连接阿里云物联网平台四、STM32环形串口缓冲区驱动程序五、STM32连接阿里云驱动程序 引言 连续写了两篇关于阿里云连接的文章&#xff0c;都是使用Arduino ESP8266 & Arduino ESP32的方式…

什么是网络安全?网络安全概况

网络安全涉及保护我们的计算机网络、设备和数据免受未经授权的访问或破坏。 这个领域包括多种技术、过程和控制措施&#xff0c;旨在保护网络、设备和数据免受攻击、损害或未授权访问。网络安全涉及多个方面&#xff0c;包括但不限于信息安全、应用程序安全、操作系统安全等 …

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models导读

通过生成一系列中间推理步骤&#xff08;即“思维链”&#xff09;显著提高大型语言模型进行复杂推理的能力 这篇论文探讨了如何通过生成一系列中间推理步骤&#xff08;即“思维链”&#xff09;显著提高大型语言模型进行复杂推理的能力。研究人员使用一种简单的方法——思维…

面试 Vue 框架八股文十问十答第十二期

面试 Vue 框架八股文十问十答第十二期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;如何在组件中重复使用…

【PyTest】玩转HTML报告:修改、汉化和优化

前言 Pytest框架可以使用两种测试报告&#xff0c;其中一种就是使用pytest-html插件生成的测试报告&#xff0c;但是报告中有一些信息没有什么用途或者显示的不太好看&#xff0c;还有一些我们想要在报告中展示的信息却没有&#xff0c;最近又有人问我pytest-html生成的报告&a…