资讯专栏INFORMATION COLUMN

Java Trouble Shooting - 关于性能瓶颈

ideaa / 3290人阅读

摘要:这个写法常常成为系统的瓶颈,如果这个地方恰好是一个性能瓶颈,修改成之后,性能会有大幅的提升。

性能优化的理念

粗略地划分,代码可分为 cpu consuming 和 io consuming 两种类型,即耗 CPU 的和耗 IO 的代码。如果当前CPU已经能够接近100%的利用率, 并且代码业务逻辑无法再简化, 那么说明该系统的已经达到了性能最大化, 如果再想提高性能, 只能增加处理器(增加更多的机器或者安装更多的CPU)。
而耗 IO 的代码,一般体现为请求某种资源,这可以是访问数据库,或者访问网络对端。

评价程序写得好不好,要看随着访问压力的上升,CPU 使用率的变化,好的代码,随着访问压力的上升,CPU 的使用率最终能趋近100%,而坏的代码,使用率始终无法趋近 100%,有可能在 70% 就已经上不去了。好的代码应该在代码本身效率足够高的情况下,通过使用并发等手段,让 CPU 的尽量地忙起来。随着访问压力的上升,CPU 使用率也上升,并且 CPU 所跑的代码都是已经无法再进行逻辑优化或者效率提升的代码,这是最理想的状态。

常见性能瓶颈 多余的同步

不相关的两个函数, 共用了一个锁,或者不同的共享变量共用了同一个锁, 无谓地制造出了资源争用,如下代码所示:

class MyClass {
  Object sharedObj;
  synchronized void fun1() {...} //访问共享变量sharedObj
  synchronized void fun2() {...} //访问共享变量sharedObj
  synchronized void fun3() {...} //不访问共享变量sharedObj
  synchronized void fun4() {...} //不访问共享变量sharedObj
  synchronized void fun5() {...} //不访问共享变量sharedObj
}

上面的代码将sychronized加在类的每一个方法上面, 违背了保护什么锁什么的原则。对于无共享资源的两个方法, 使用了同一个锁, 人为造成了不必要的锁等待。 上述的代码可作如下修改:

class MyClass {
  Object sharedObj;
  synchronized void fun1() {...} //访问共享变量sharedObj
  synchronized void fun2() {...} //访问共享变量sharedObj
  void fun3() {...} //不访问共享变量sharedObj
  void fun4() {...} //不访问共享变量sharedObj
  void fun5() {...} //不访问共享变量sharedObj
}
锁粒度过大

对共享资源访问完成后, 没有将后续的代码放在synchronized同步代码块之外。 这样会导致当前线程长时间无谓的占有该锁, 其它争用该锁的线程只能等待, 最终导致性能受到极大影响。如下代码所示:

void fun1() {
    synchronized(lock){
    ... ... //正在访问共享资源
    ... ... //做其它耗时操作,但这些耗时操作与共享资源无关
  }
}

上面的代码, 会导致一个线程过长地占有锁, 而在这么长的时间里其它线程只能等待。应将上述代码作如下修改,在多 CPU 的环境中,可获得性能的提升:

void fun1() {
  synchronized(lock) {
    ... ... //正在访问共享资源
  }
  ... ... //其它耗时操作代码拿到synchronized代码外面
}
字符串连接的滥用
String c = new String("abc") + new String("efg") + new String("12345");

每一次+操作都会产生一个临时对象, 并伴随着数据拷贝, 这个对性能是一个极大的消耗。 这个写法常常成为系统的瓶颈, 如果这个地方恰好是一个性能瓶颈, 修改成StringBuffer之后, 性能会有大幅的提升。

不恰当的线程模型

在多线程场合下, 如果线程模型不恰当, 也会使性能低下,在网络IO的场合, 使用消息发送队列和消息接收队列来进行异步IO,性能会有显著的提升。


不恰当的 GC 参数

不恰当的GC参数设置会导致严重的性能问题,比如堆内存设置过小导致大量的 CPU 时间片被用来做垃圾回收

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69919.html

相关文章

  • Java Trouble Shooting - 使用线程栈

    摘要:线程的优先级代表线程的优先级为线程代表线程为,而代表该线程对应的操作系统级别的线程。若是有运行图形界面的环境,也可以使用一些图形化的工具,例如来生成线程栈文件。使用线程栈定位问题发现死锁当两个或多个线程正在等待被对方占有的锁,死锁就会发生。 什么是线程栈(thread dump) 线程栈是某个时间点,JVM所有线程的活动状态的一个汇总;通过线程栈,可以查看某个时间点,各个线程正在做什么...

    DataPipeline 评论0 收藏0
  • walle 2.0 预览版惊艳亮相,上线部署系统

    摘要:万众瞩目的开源免费代码部署平台,终于出预览版了。惊艳无比,一系列大家无比期待的逐一亮相,代码发布终于可以不只能选择,有了一个可自由配置项目,更人性化,支持多用户多项目多环境同时部署的开源上线部署系统。 万众瞩目的开源免费代码部署平台 walle 2.0,终于出预览版了。walle 2.0 惊艳无比,一系列大家无比期待的 Feature 逐一亮相,代码发布终于可以不只能选择 jenkin...

    XFLY 评论0 收藏0
  • TiDB 3.0.0-rc.1 Release Notes

    摘要:用动态规划决定连接的执行顺序,当参与连接的表数量不多于时启用。在逻辑优化阶段消除聚合函数时特殊处理,防止产生错误的执行结果。该特性通过对进行执行计划绑定,以确保执行稳定性。执行引擎支持对和算子进行内存追踪控制。 2019 年 5 月 10 日,TiDB 发布 3.0.0-rc.1 版,对应的 TiDB-Ansible 版本为 3.0.0-rc.1。相比 3.0.0-beta.1 版本,...

    you_De 评论0 收藏0
  • 浅述APM采样与端到端

    摘要:主题大纲浅述采样与端到端何为何为端到端何为采样的做法与弊端嘉宾介绍高驰涛,官方开发组成员,作者,云智慧高级架构师。 极牛技术实践分享活动 极牛技术实践分享系列活动是极牛联合顶级VC、技术专家,为企业、技术人提供的一种系统的线上技术分享活动。 每期不同的技术主题,和行业专家深度探讨,专注解决技术实践难点,推动技术创新,每两周的周三20点正式开课。欢迎各个机构、企业、行业专家、技术人...

    seasonley 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<