像ProGuard一样的静态Java字节码优化器,具有逃逸分析功能?

7

基于逃逸分析的优化是Proguard计划中的一个功能。与此同时,是否已经存在像Proguard一样需要逃逸分析的优化工具?


2
Sun的HotSpot JVM自从Sun Java 6 Update 14版本开始就内置了逃逸分析功能。您需要使用-XX:+DoEscapeAnalysis来启用它。详情请参阅:http://java.sun.com/javase/6/webnotes/6u14.html - Jesper
1
在u18及更高版本上禁用了逃逸分析。 - gustafc
1
它仅在服务器VM上可用,而在Android的Dalvik VM上根本不可用,也没有我所知道的任何Java ME变体。重点是提前进行逃逸分析,以便即使在VM中未启用也能获得好处。 - Jeremy Bell
2
它在u21中重新启用,并且现在默认情况下已启用:http://download.java.net/jdk6/6u21/promoted/b05/changes/JDK6u21.list.html(请参见id 6873799) - Mene
这很好,但对我没有帮助。我不是使用HotSpot,而是在Android上使用dalvik VM,它可能永远不会有像逃逸分析这样昂贵的JIT优化(它们更喜欢快速启动时间而不是绝对性能)。 - Jeremy Bell
显示剩余2条评论
2个回答

3

是的,我认为Soot框架执行逃逸分析。


1
你如何配置Soot以进行整个程序优化(例如逃逸分析),用于Android应用程序?似乎该框架仅假定您有一个主函数并从那里构建调用树,但是Android应用程序没有主函数。Proguard允许您保留多个类,因此类中的每个方法都成为整个程序优化中调用树分析的新“根”。我找不到Soot的类似选项。 - Jeremy Bell
我将此标记为答案。我在这里打开了一个新的问题,专门讨论没有主函数的soot和整体程序优化:http://stackoverflow.com/questions/3093648/how-to-use-soot-to-do-whole-program-optimizations-on-android-applications - Jeremy Bell

1

你对编译器级别的逃逸分析有什么期望?Java类更像是C语言中的目标文件 - 它们在JVM中链接,因此逃逸分析只能在单个方法级别上执行,这具有有限的实用性,并且会妨碍调试(例如,您将无法通过某些代码行)。

在Java的设计中,编译器相当愚蠢 - 它检查正确性(如Lint),但不尝试进行优化。聪明的部分放在JVM中 - 它使用多种优化技术,在当前平台和条件下产生良好的性能代码。由于JVM知道当前加载的所有代码,因此它可以假设比编译器更多,并执行推测性优化,一旦假设无效即可撤销。HotSpot JVM可以在函数运行时(例如,在循环的中间,随着代码变得“热”)动态地用更优化的版本替换代码。

当不在调试器中时,具有非重叠生命周期的变量会被折叠,不变量会被提升出循环,循环会被展开等。所有这些都发生在JIT编译的代码中,并且取决于在该函数中花费的时间(在从未运行的代码上花费时间进行优化没有多大意义)。如果我们预先执行其中一些优化,JIT将拥有更少的自由度,整体结果可能是净负面。

另一个优化是堆栈分配不逃逸当前方法的对象 - 在某些情况下会执行此操作,尽管我在某个地方读到过一篇论文,其中详细的逃逸分析所需的时间与通过优化获得的时间之间的比较表明它不值得,因此当前策略更具启发性。

总的来说,JVM对您的原始代码了解越多,它就能够更好地优化它。而JVM所做的优化不断改进,因此我认为只有在谈论像手机这样非常受限和基本的JVM时才考虑编译代码优化。在这些情况下,您无论如何都要通过混淆器运行应用程序(缩短类名等)。


我只对Dalvik VM感兴趣,并且至少在接下来的6个月内锁定了1.5 / 1.6平台,至少一年锁定2.1。即使我可以针对2.2,JIT也经过专门调整,以具有非常快的启动时间并尽可能少地在JIT中花费时间,因此昂贵的优化(如逃逸分析加标量替换)完全不可行。我特别寻找的是一种静态字节码优化器,它可以基于逃逸分析进行标量替换,用于短暂的临时对象。 - Jeremy Bell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接