前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java性能优化实例分析

java性能优化实例分析

作者头像
叔牙
发布2020-11-19 14:39:18
7740
发布2020-11-19 14:39:18
举报
文章被收录于专栏:一个执拗的后端搬砖工
代码语言:javascript
复制
之前写过一些java性能优化的总结,
但是没有依照具体的实例分析,看起来比较空洞,
此篇我将依照在珍爱网的阅读和
改造别人写的代码的过程中遇到的一些
比较典型的可调优的例子,
接下来将一一做分析对比和优化:
1.过早初始化&无用初始化
代码语言:javascript
复制
分析:这段代码有三个比较观点的地方,
我用红色框进行了标注;
I) allProductList进行初始化
II)调用服务根据结果对
    allProductList重新赋值
III)调用allProductList的size
    方法获取列表长度赋值给count2问题:
allProductList被初始化后,
new了一个列表(默认长度10)出来,
创建了一个10个FinanceServiceProduct
大小的堆空间,接着调用一个dubbo服务,
将查询结果列表赋值给allProductList,
也就是allProductList重新指向了一个新的内存地址,
之前创建的列表对象失去引用被gc线程回收,
最后调用size方法之前没有对
allProductList做判空处理,导致线上出现
空指针异常;这个地方可能开发人员会有
一个幻觉,我明明初始化了一个空list,
为什么还报NullPointerException,
因为第二步中dubbo调用返回结果可能会
为null,所以第一步的初始化完全没有
意义(刚new完就被回收)优化结果:
第一步中List<FinanceServiceProduct> 
    allProductList = null;//只做声明不做初始化
第三步if(null != allProductList)
     Integer count2 = allProductList.size();
     //做调用之前判空
2.循环中做服务调用&数据库io操作
代码语言:javascript
复制
分析:这段代码是在分页查询的结果列表中
做服务调用(服务中有数据库IO操作),
每次查询出10条数据问题:
每次循环中有四个dubbo服务调用和
数据库查询,那么我每次查询都操作
都会产生10*4的dubbo服务网络开销
和数据库IO,想问下这样的程序性能
能好到那里去;这样就会产生一系列的问题;
I)过度的网络开销(太多的服务调用)
II)在高并发场景下数据库根本扛不住
这样的操作,尽管只是查询解决方案:
批量操作,将每次分页查询出来的10条
数据中的参数装配成列表,交给服务
一次性查询出来10条结果,然后再在上述
代码中循环装配结果信息(java内存操作
性能和速度远远强于网络传输和数据库IO),
优化完后并不是避免了所有IO和dubbo服务调用,
有原来的40次变成了4次,在并发环境下
和网络不好的场景下性能提升肯定是数量级的
3.无效的返回类型&异常堆栈信息丢失
代码语言:javascript
复制
分析: 由于公司新项目做了前后端分析,
交互方式都是json的数据格式,服务端
接口返回给前端的响应结果严格规定要
包含code和msg属性,在处理正确的
情况下可能会有data属性问题:
I)第一个红框处,如果req==null,
那么直接结束调用返回给前端,
但是前端拿不到任何响应数据
II)第二个红框处,如果出现异常,
LOGGER打印的信息吃掉了异常堆栈信息,
前端拿到请求异常的响应信息,
但是后台查阅日志是分析不出来是
什么异常的解决方案:
I)第一个红框处response加入参数非法code和msg
II)第二个红框处LOGGER打印日志加入e异常堆栈
4.冗余服务调用
代码语言:javascript
复制
分析:这是一个和数据库交互的dao层分页查询,
大概意思是先根据条件查询出总数量,
在查询具体的数据列表问题:这段代码不仔细分析是看不出来
什么问题的,想必在屏幕前的你也是这样想的,
但是有一个场景,假如说
标红框的地方查询结果是0,count为0,
也就是说我根据同样的条件查询列表总数为0,
那么我以通用的条件再去查询
列表肯定返回也是null,这种场景count
返回0时,还有没有必要再去数据库查询
出来一个null结果?解决方案:
在红框下边加一段代码if(count <= 0 ) 
return null;//如果总数为0,不在去查列表,
直接返回调用
这样的高并发的场景下也能带来
不小的性能提升
5.频繁的Map数据get和put
代码语言:javascript
复制
分析:这段代码的大概意思是,
分页查询数来一个列表,
然后循环队列表进行转配问题:循环中对map进行get和put操作,
每次循环从map中取出就得值,
然后加上新元素值,再放入map,
导致频繁的map读取和
存入操作,这样会有频繁的cpu
计算和map的重新hash计算
(HashMap是基于数组和链表实现)解决方案:在循环外声明变量值,
循环中计算变量值,循环结束一次性
map的put操作,省去了频繁的get和put
6.将计算的压力放在了数据库层
代码语言:javascript
复制
分析:上段代码中第二个(暂时忽略第一个)
红框标注的部分,频繁资利用数据库自带的
函数进行计算和统计问题:乍眼一看,这段代码也没有什么问题;
这里我想给大家明确一个概念,
数据库为什么叫做数据库,
是因为其有独特的最擅长的功能,
就是查询和存储,不是数据库不能
够计算而是让数据库计算,效率真的高吗?
性能真的好吗?让数据库计算,
除了增加数据库的压力,在高并发
场景下会导致数据库所在主机的cpu迅速飙升。解决方案:所以,既然是数据库,
那么就让数据库做他最擅长的
存储和查询吧,计算这种事情还是
交给java程序比较好,
另外,在大部分项目中,数据库和
java服务相比,数据库属于稀缺资源,
我们可以对一个dubbo模块部署
多个服务实例,但是同时部署多个
mysql实例,会产生一系列的问题
需要去维护(主从复制导致的数据不一致,集群的维护)

原创不易,请多多支持!!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PersistentCoder 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.过早初始化&无用初始化
  • 2.循环中做服务调用&数据库io操作
  • 3.无效的返回类型&异常堆栈信息丢失
  • 4.冗余服务调用
  • 5.频繁的Map数据get和put
  • 6.将计算的压力放在了数据库层
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档