JVM调优概述

JVM调优概述

JVM调优标志

除极少数外,JVM主要接受两类调优标志:布尔标志,附带参数标志;

  • 布尔参数的语法为-XX:+FlagName表示开启,-XX:-FlagName表示关闭。
  • 附带参数的语法为-XX:FlagName=something,将FlagName的值设置为something。

每个标志都有它的默认值,我们可以执行以下命令查看。

1
java -XX:+PrintFlagsFinal

这些标志在Client以及Server类虚拟机上具有不同的默认值,现在讨论这个已经没有意义了,从JDK 9开始Oracle不再提供32位的JDK下载了。
备注:在Microsoft Windows上运行的任意32位JVM(无论cpu的核心数)以及单cpu的(不论是什么操作系统)运行的32位,都是Client类虚拟机。所有其他机器(包括64位虚拟机)都被认为是Server类虚拟机。

全面的性能调优

编写更好的算法

不言而喻.

编写更少的代码

  • 要编译的代码越多,等待程序启动所消耗的时间越长。
  • 要创建的对象越多,垃圾收集的工作量越大。
  • 要分配的对象越多,GC的周期越长。
  • 要从磁盘装载到JVM的类越多,程序启动所花费的时间越长。
  • 要执行的代码越多,机器硬件缓存的效率越低。
  • 执行的代码越多,花费的时间越长。

无法取胜的战争

所有应用程序的性能随着时间,即新版本的发布而降低.但由于硬件的改善使得新程序的运行速度可以接受,所以不会有人注意到性能上的差异。

随着新特性的添加和新要求的采纳,程序会越来越大,越来越慢.这种现象我们总结为“积少成多”原则。随着功能的增加,性能测试很快就会检测到资源瓶颈。而性能调优小组可以修正主要的性能衰减。

过早优化

我们不能把大量的时间都耗费在那些小的性能改进上。最终我们应该编写清晰,直接,易读和易理解的代码,不能为了性能而过早的编写复杂的程序结构(算法和设计带来的)。那些真正的优化最好留到最后,等到性能分析表明这些措施有巨大收益的时候才进行。
备注:过早优化不包括已知的对性能不好的代码结构。

其他:数据库很有可能是瓶颈

如果我们开发的是独立运行的Java程序,性能就只与应用本身相关。一旦添加了外部资源(例如数据库),那么这两者的性能都很重要。在分布式环境中,比如Java EE服务器,负载均衡器,数据库,Java应用服务器的性能问题可能只是其中的很小一部分。

对于整个系统,我们需要采用结构化的方法针对系统的所有方面分析性能。CPU使用率,I/O延迟,系统整体的吞吐量都必须测量和分析。只有到那时,我们才能确定是那个组件导致了性能瓶颈。

不只JVM有BUG和性能问题

  • 运行环境中的任何部分都可能会引起性能问题,包括测试框架。
  • 不要忽略初步分析,如果数据库是瓶颈,那么无论如何优化访问数据库的Java程序,都无助于整体性能,实际上可能适得其反。作为一般性原则,系统负载越大,系统性能越糟糕。如果更改Java应用使得它更有效,这只会增加已经过载的数据库的负载 ,整体性能实际反而会下降。导致的风险是,可能会得出错误的结论,即认为不应该改进JVM。

增加系统某个组件的负载导致整个系统性能变慢,这一原则不仅适用于数据库.CPU密集型应用,或者越来越多的线程试图获取已经有线程等待的锁,还有一些其他的场景都适用这一原则

常见的优化

一般而言,常用的用例场景才是性能优化真正应该关注的重点.

  • 借助性能分析来优化代码,重点关注性能分析中最耗时的操作。
  • 利用奥卡姆剃刀原则诊断性能问题,性能问题最有可能的原因应该是最容易解释的:新代码比机器配置更可能引入性能问题,机器配置比JVM或者操作系统的bug更容易引入性能问题。
  • 为应用中最常用的操作编写简单的算法。

总而言之

多数情况下,JVM只占整体性能的一小部分。你需要对Java所在系统的环境进行整体系统调优,数据库和其他后台运行系统的性能的重要性不亚于JVM。此外,JVM与系统其他部分的交互对系统的影响也同样重要。

参考

  1. Oracale JDK下载地址汇总