Java 在 Linux 中性能调优最佳实践

本文能帮助你把Java应用程序性能发挥到极值。

在应用程序进行性能调优时,应当在优化代码的同时考虑代码运行的硬件。本文将介绍在Linux上把Java性能推到极致需要注意的方方面面。

 

线程争用

  1. 减少关键部分的代码量。

  2. 优先考虑使用同步代码块,其次才是同步方法。

  3. 优先考虑在同步代码块上加锁。

  4. 密切注意锁定资源的顺序,你可能会遇到死锁。

  5. 隔离低并发、中等并发和高并发用例,区别对待。

  6. 对低并发和中等并发尽可能使用CAS(Compare-And-Swap)操作。

  7. 请勿在同步代码块或已加锁情况下调用第三方Web服务或执行其他需要长时间运行的方法。

  8. 对比wait、notify和notifyAll机制,更推荐lock、CountDownLatch、CyclicBarrier这样的高级线程结构。

  9. 长时间运行的线程应允许中断。线程内部定期检查“interrupted”状态。

  10. 当读操作数量远大于写操作时,建议使用ReadWriteLock。它提高了读操作并发性。

  11. 仅在有多个线程访问数据结构的情况下才考虑使用并发数据结构。

  12. 不要在应用程序中到处修改状态。对可变状态加以限制并有意识地进行处理。这样可以减少锁的数量以及各种线程争用问题。

  13. 注意下面的自旋锁。它们会占用CPU资源。while(true) {//执行操作不休眠}

  14. 在这种无限while循环中,一定要合理地休眠。轮询线程就是一个这样的示例。

 

堆配置与垃圾回收

  1. 遵守用StringBuilder处理日志消息的标准实践。

  2. 分析应用程序,设置合理的堆与和垃圾收集参数。

  3. 不合理的GC设置可能会占用CPU资源,造成应用程序长时间暂停,由于内存不足导致应用程序崩溃,以及因并发模式故障带来的内存溢出或应用假死。

  4. 为了保证低延迟,应用程序需使用并发标记(Concurrent Mark)以及 CMS 或 G1 GC扫描算法。

 

避免磁盘交换

务必保证有足够的RAM提供给Java进程,Java进程发生磁盘交换是性能杀手。如果应用程序交换到磁盘,由于在GC期间必须从磁盘读取对象,垃圾回收周期会更长。

 

磁盘

  1. 使用异步logger记录日志。

  2. 在允许的情况下采用上下文日志。上下文日志是指将API调用的日志或事件存储到上下文对象中,并通过异步logger记录上下文数据。这将大大提高Java应用程序的性能,并且更易于排除故障。

  3. 无论进行何种持久性,优先考虑数据库而非本地磁盘。数据库针对磁盘读写进行了优化。

CPU

  1. 使用线程池。尽管线程本身是轻量级,但是创建线程仍然会带来很大的开销。

  2. 盲目地创建线程会导致上下文切换与平均负载激增,超过指定的阈值后会造成应用程序和计算机无响应。

  3. 除了CPU利用率,还要注意平均负载和上下文切换。它们在一起组成了性能相关的完整信息。

密切注意网络

  1. 查找网络上的丢包情况。

  2. 数据包丢失可能意味着应用程序太忙无法接收数据包,或者所处的网络发生拥塞。

  3. 如果有必要,请调整网络缓冲区大小。

 

使用缓存

  1. 缓存常用数据减少数据库访问。

  2. 针对每个用例分别进行缓存配置,包括eviction、expiry、size、consistency和concurrency。

  3. 将读密集型缓存与写密集型缓存分开,这样获得更好的锁定效果。

  4. 谨慎地使用分布式缓存。不恰当地使用分布式缓存会引入新问题,而不是解决现有问题。

 

通讯

  1. 对于近距离实时通信优先考虑异步通信。

  2. 设置发送API或RMI调用超时,这样某个长时间运行的操作不会破坏整个生态系统。

 

分析并记录更改

持续进行性能分析并记录你的更改。清晰地记录做出决定的原因。今天的重大决策可能到了明天就失去意义。这种情况发生时,工程师应该有足够的信息来还原或扩展应用程序。这就是应用程序的生存之道。没有人愿意坐在一颗定时炸弹上,并且不知道它什么时候会爆炸。

性能分析工具

  1. Jstack用来收集线程dump。

  2. Jmap用来收集堆dump和活动对象计数。

  3. Jvisualvm或Jconsole:用来分析堆、线程、收集线程dump,JDK默认提供。

  4. Eclipse内存分析器(MAT):用来分析堆dump。

  5. 线程Dump分析器(TDA):用来分析线程dump,检测长时间运行的线程与死锁。

 

性能调优建议

在项目早期就进行性能调整计划和预算,但不要过早开始执行。这样可能会让核心业务逻辑变得混乱。我知道有一个应用程序过早进行优化,限制从数据库中获取的记录数,但是这一切并没有记录。

结果出现了各种各样的问题。由于这段代码位于底层,导致花了很多时间才得以解决。当然,如果在这方面你已经身经百战,可以忽略这条建议。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值