通过代码在Java中的性能?

通过代码在Java中的性能?,java,performance,optimization,Java,Performance,Optimization,首先,我应该提到的是,我知道性能优化可以是非常特定于项目的。我现在基本上没有面临这些特殊问题。我面临着JVM本身的一系列性能问题 我现在想知道: 哪种代码优化有意义 从编译器的角度来看:对于 支持垃圾的示例 收集器I将变量声明为 最终-非常符合PMD的要求 这里是Eclipse的建议 有哪些最佳实践:vmargs, 堆和其他东西传递给 用于初始化的JVM。我该怎么去 这里的正确值是多少?有吗 公式还是反复尝试 Java自动化程度很高,在字节码级别进行了很多优化。然而,我认为,为了工作,大部分

首先,我应该提到的是,我知道性能优化可以是非常特定于项目的。我现在基本上没有面临这些特殊问题。我面临着JVM本身的一系列性能问题

我现在想知道:

  • 哪种代码优化有意义 从编译器的角度来看:对于 支持垃圾的示例 收集器I将变量声明为 最终-非常符合PMD的要求 这里是Eclipse的建议
  • 有哪些最佳实践:vmargs, 堆和其他东西传递给 用于初始化的JVM。我该怎么去 这里的正确值是多少?有吗 公式还是反复尝试
Java自动化程度很高,在字节码级别进行了很多优化。然而,我认为,为了工作,大部分工作必须由开发人员进行规划


那么,如何提高Java程序的速度呢?:)

很难彻底回答这个问题,因为你甚至没有提到你在谈论什么样的项目。它是桌面应用程序吗?服务器端应用程序

桌面应用程序喜欢应用程序启动时间,因此HotSpot客户端VM是一个良好的开端。客户端应用程序不一定总是需要所有的堆空间,所以在启动堆和最大堆之间保持良好的平衡是很有用的。(比如,可能是-Xms128m-Xmx512m)

服务器应用程序支持总体吞吐量,这是HotSpot服务器VM的优化目标。您应该始终在服务器应用程序上分配相同的最小和最大堆大小。在垃圾收集过程中,在系统级必须执行malloc()和free(),这会增加成本。使用类似-Xms1024m-Xmx1024m的内容

还有几个不同的垃圾收集器,它们被调优为不同的应用程序类型


如果您想了解有关Java 6中垃圾回收器和其他性能相关项目的更多信息,请通读。

通常,您需要对Java进行两种性能优化:

  • 算法优化。选择一个算法,它的行为就像你需要的那样。例如,一个简单的算法可能对小数据集的性能最好,但准备一个更智能的算法的开销可能首先会对更大的数据集产生回报

  • 瓶颈识别。在这里,您需要熟悉一个分析器,它可以告诉您问题是什么(人类总是猜错)-内存泄漏?,慢速方法?等一个好的开始是VisualVM,它可以连接到正在运行的程序,并且在最新的Sun JDK中提供。当你知道这个问题时,你可以解决它

从编译器的角度来看,哪种代码优化是有意义的:例如,为了支持垃圾收集器,我声明变量为final,这在很大程度上遵循了PMD在Eclipse中的建议

假设您正在谈论可以对代码进行的潜在微优化,那么答案几乎是否定的。提高应用程序性能的最佳方法是运行探查器,找出性能瓶颈所在,然后找出是否可以采取任何措施来加快它们的速度

在大多数情况下,所有经典的技巧,如声明类、变量和方法final、重新组织循环、更改基元类型,都是一种浪费。JIT编译器通常可以比您做得更好。例如,最近的JIT编译器将分析所有加载的类,以确定哪些方法调用不受重载的影响,而无需将类或方法声明为
final
。然后它将使用更快的调用序列,甚至内联方法体

事实上,Sun专家说,一些程序员尝试优化失败,因为它们实际上使JIT编译器更难应用它所知道的优化

另一方面,更高层次的算法优化绝对值得。。。假设探查器告诉您,您的应用程序在该代码区域花费了大量时间

在不寻常的情况下,使用数组而不是集合可能是一种值得优化的方法,在极少数情况下,使用对象池也可能是一种值得优化的方法。但是这些优化1)会使代码更复杂,更容易出现错误;2)如果使用不当,会降低应用程序的速度。这些类型的优化只能作为最后的手段来尝试。例如,如果您的评测表明某某的
HashMap
是CPU瓶颈或内存占用,那么最好查找现有的专门的
Map
Map
类库类,而不是尝试自己使用数组实现映射。换句话说,在高层次上进行优化

如果您花费的时间足够长或者您的应用程序足够小,那么仔细的微优化可能会使您的应用程序(在给定的JVM版本/硬件平台上)比仅仅依赖JIT编译器更快。如果您正在用Java实现一个小型应用程序来进行大规模的数字运算,那么微优化的回报可能是可观的。但这显然不是一个典型的案例!对于典型的Java应用程序,工作量足够大,性能差异也足够小,因此不值得进行微优化


(顺便说一句,我不明白声明变量如何对GC性能产生任何可能的影响。无论变量是否为最终变量,GC都必须在每次遇到变量时对其进行跟踪。此外,最终变量在某些情况下确实可以更改是一个公开的秘密,因此GC假设它们会更改是不安全的不是。不安全,如“创建悬空指针导致JVM崩溃”。

今天的JVM在性能方面惊人地强大。几乎在所有情况下,任何可以应用的微优化都只会对性能产生非常小的影响