![]() |
1
5
我经常看到这个。顺序通常是:
这种现象发生在每种语言中,但在爪哇,C,C,其中抽象已被推向极端。因此,无论如何,要了解最佳实践,同时也要了解 简单软件 是。通常,它包括将这些最佳实践保存到真正需要它们的环境中。 |
![]() |
2
6
假设您正在讨论可以对代码进行的潜在微观优化,那么答案几乎为零。提高应用程序性能的最佳方法是运行一个探查器,找出性能瓶颈在哪里,然后找出是否有任何方法可以加快它们的速度。
在大多数情况下,所有的经典技巧,比如声明类、变量和方法、重新组织循环、更改基元类型,都是浪费精力的。JIT编译器通常比您能做的更好。例如,最近的JIT编译器将分析所有加载的类,以确定哪些方法调用不受重载影响,而无需将类或方法声明为
实际上,Sun专家说,一些程序员尝试优化失败,因为它们实际上使JIT编译器难以应用它所知道的优化。 另一方面,更高层次的算法优化是值得的…前提是探查器告诉您,您的应用程序在该代码区域花费了大量时间。
在不常见的情况下,使用数组而不是集合是一种有价值的优化,在极少数情况下,使用对象池也是如此。但是这些优化1)会使代码更复杂,更容易出错;2)如果使用不当,会降低应用程序的速度。这些优化只能作为最后的手段来尝试。例如,如果您的分析显示
如果您花费足够长的时间或者您的应用程序足够小,那么仔细的微优化可能会使您的应用程序(在给定的JVM版本/硬件平台上)比仅仅依赖于JIT编译器更快。如果你在Java中实现一个小规模的应用程序来进行大规模的数字压缩,那么微优化的回报可能是相当可观的。但这显然不是典型的情况!对于典型的Java应用程序来说,工作量足够大,性能差异小到微优化是不值得的。 (顺便说一下,我不知道如何声明一个变量可以对GC性能产生任何可能的影响。每次遇到变量时,GC都必须跟踪它,不管它是否是最终变量。此外,在某些情况下,最终变量实际上可以更改是一个公开的秘密,因此GC认为最终变量不会更改是不安全的。不安全,如“创建一个悬空指针导致JVM崩溃”。) |
![]() |
3
3
编译器无法推理的所有编译器,因为编译器非常愚蠢,Java没有“按合同设计”(因此,不能帮助哑编译器对代码进行解释)。 例如,如果您正在处理数据并使用int[]或long[]数组,那么您可能知道有关数据的一些信息,即 不可能的 对于编译器来说,您可以使用低级的位打包/压缩来改进代码中该部分的引用位置。 到了那里,看到了巨大的加速。对于“超级智能编译器”来说就这么多了。 这只是一个例子。有很多这样的案例。 记住编译器是 真的? 笨蛋:不知道 如果(Math.Abs(42)>0) 将永远返回真。 对于那些认为编译器是“聪明”的人来说,这应该给人们一些想法。(如果Java有DbC的话,情况就不同了,但它没有。)
真正的答案是:不应该有。不幸的是,由于Java部分的严重失败,这种情况是如此的悲惨以至于需要如此低级的黑客行为。哦,还有一个“小”细节:使用vm微调只适用于服务器端应用程序。它不适用于桌面应用程序。 任何在数百台或数千台机器上安装的Java桌面应用程序上的人,都知道什么是好的。 这个 问题是:完全GC暂停,使您的应用程序看起来像是坏了。苹果操作系统10.4上的虚拟机出现在我的脑海中,因为它是特别的afwul,但是 所有 合资公司应遵守该问题。 更糟糕的是:当您的应用程序将在数百/数千种不同的配置上运行时,不可能在不同的OSE/VMS/内存配置中“微调”GC的参数。
但这并不坏:首先,您不应该关心超低级别的细节,比如GC“微调”。这一事实被暗示是对Java有一个主要问题的一个领域的证明。 但这显然是错误的。Trove的“tintingthashmap”围绕hashmap<integer,integer>循环运行是有原因的。 -xxgc多道刻痕 那个 毕竟在庆功会上很棒。 为了回答你的问题:你如何加快Java程序?简单,就像特洛伊人做的那样:停止不必要地创建大量的对象,停止不必要的自动(联合国)拳击原语,因为它们 将 取消应用程序的性能。 TintIntHashMap 拥有 默认的hashmap<integer,integer>原因:与我的应用程序现在的原因相同 许多的 比以前快。 我不再相信垃圾 “对象创建成本为零” 和 “GC是超级优化的,不用担心” . 我用Java来压缩数据(我知道,我有点疯狂),使我的应用程序更快的一件事就是停止相信围绕“便宜的对象创建”和“惊人的快速GC”的所有宣传。 事实是: 与其尝试微调GC设置,不如先停止创建那么多垃圾。 . 这可以这样说:如果改变GC设置彻底改变了应用程序的运行方式,那么可能是时候怀疑是否真的需要你创建的所有不必要的垃圾对象了。 哦,你知道吗,我敢打赌,我们会看到越来越多的发行说明,解释为什么Java版本X.Y.Z的GC比X.Y.Z-1的GC更快。 |
![]() |
4
2
通常有两种性能优化需要与Java进行:
|
|
5
1
很难回答得太彻底,因为你甚至没有提到你在谈论的是什么样的项目。它是桌面应用程序吗?服务器端应用程序? 桌面应用程序有利于应用程序的启动时间,因此Hotspot客户机VM是一个很好的开始。客户机应用程序不一定总是需要所有的堆空间,所以在开始堆和最大堆之间保持良好的平衡是有用的。(例如,可能是-xms128m-xmx512m) 服务器应用程序支持整体吞吐量,这是Hotspot服务器虚拟机所需要的。在服务器应用程序上,您应该始终分配相同的最小和最大堆大小。在垃圾收集过程中,在系统级别上需要花费malloc()和free()来增加成本。使用类似-xms1024m-xmx1024m的内容。 还有几个不同的垃圾收集器,它们被调到不同的应用程序类型。 阅读 http://java.sun.com/performance/reference/whitepapers/6_performance.html 如果您想从Java 6获取更多关于垃圾收集器和其他与性能相关的项目的信息。 |
![]() |
6
1
今天的JVM在性能方面惊人地强大。实际上,在所有情况下,您可以应用的任何微优化对性能的影响都非常小。如果您看看典型的语言结构(例如for vs while)是如何转换为字节码的,这很容易理解——它们几乎是不可区分的。 使方法/变量最终化对一个合适的JIT'dJVM的性能绝对没有影响。JIT将跟踪哪些方法确实是多态的,并尽可能优化动态调度。静态方法仍然可以更快,因为它们没有这样的引用=少一个局部变量(同时限制了它们的应用)。最有效的微优化不是Java特定的,例如,由于处理器的分支错误预测,带有大量条件语句的代码可能变得非常慢。有时条件可以被其他连续的代码流构造(通常以可读性为代价)替换,从而减少预测失误的分支数(这适用于以某种方式编译为本机代码的所有语言)。 请注意,分析程序往往会夸大花费在短时间内(通常称为方法)的时间。这是因为分析程序需要检测代码以跟踪调用——这会干扰JIT内联这些方法的能力(并且检测开销明显大于实际执行方法体所花费的时间)。手动内联,虽然在剖析器下明显的性能提升在大多数情况下在“真实世界”条件下没有效果。不要纯粹依赖于分析程序的结果,请验证您所做的优化在实际运行时条件下也具有实际影响。 显著的性能提升只能通过减少完成的工作量、更适合缓存的数据布局或更高级的算法来实现。Java部分限制了缓存友好数据布局的可能性,因为您无法控制构成数据结构的部分(数组/对象)将在内存中彼此相关。尽管如此,在为工作选择正确的数据结构时还是有很多机会可以产生巨大的差异(例如,ArrayList和LinkedList)。 你几乎无能为力去帮助垃圾收集器。然而,值得注意的一点是,虽然Java中的对象分配非常快,但仍然存在对象初始化的成本(主要是在您的控制之下)。创建大量(短寿命)对象的应用程序的性能差更可能是由于缓存利用率差而不是垃圾收集器的工作造成的。 不同的应用程序类型需要不同的优化策略-因此,在询问特定的优化之前,先了解应用程序真正花在哪里。 |
![]() |
7
1
如果您的应用程序遇到性能问题,您应该认真考虑尝试一些分析(例如:hprof),以查看问题本质上是否是算法问题,并检查GC性能日志(例如:verbose:gc),以查看是否可以从调优JVM GC选项中获益。 |
![]() |
8
1
值得注意的是,编译器几乎没有优化,而JVM也没有在字节代码级别进行优化。大多数优化是由jvm中的jit执行的,它选择如何将代码转换为本机代码。 优化代码的最佳方法是使用事件探查器,它可以测量应用程序在提供实际数据集时使用的时间和资源量。没有这些信息,你只是猜测,你可以改变大量的代码,在那里它真的,真的不重要,并发现你在这个过程中添加了错误。 许多人得出的结论是,选择代码是不值得的,甚至会适得其反,因为这样做会浪费时间并引入错误,我认为95%以上的代码都是这样的。但是,有了Approviler,您可以测量关键的代码片段,并优化价值5%的优化,并仔细完成,您不会因为尝试优化代码而遇到太多问题。 |
|
user29759326 · 如何返回递归函数中的最后一个值? 4 月前 |
|
malife89 · 将java中的字符串读取为正确的日期格式 4 月前 |
![]() |
Tim · 在java中,有没有更快的方法将字节数组写入文件? 4 月前 |
![]() |
rudraraj · java中未声明最终变量 5 月前 |
![]() |
Bala Ji · 以下BFS的实施效率如何? 5 月前 |