Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中是否有零时间启动(无重新编译)可切换条件标志?_Java_Performance_Debugging_Classloader_Jit - Fatal编程技术网

Java中是否有零时间启动(无重新编译)可切换条件标志?

Java中是否有零时间启动(无重新编译)可切换条件标志?,java,performance,debugging,classloader,jit,Java,Performance,Debugging,Classloader,Jit,我正在寻找一种方法,为if条件提供最快的开/关标志(我的意思是零时间-编译/类加载/JIT时间解析)。当然,此条件在每次应用程序运行时(启动时)只会更改一次 我知道“编译时常量if条件”可以有条件地编译,并且可以从代码中删除整个条件。但是,在不需要重新编译源代码的情况下,最快(可能也是最简单)的替代方案是什么 我可以将condition移动到使用单个类和带有condition的方法分离.jar,在这里我生成该.jar的两个版本,并在应用程序启动时在类路径中切换这些版本吗JIT是否会在单独的.ja

我正在寻找一种方法,为
if
条件提供最快的开/关标志(我的意思是零时间-编译/类加载/JIT时间解析)。当然,此条件在每次应用程序运行时(启动时)只会更改一次

我知道“编译时常量if条件”可以有条件地编译,并且可以从代码中删除整个条件。但是,在不需要重新编译源代码的情况下,最快(可能也是最简单)的替代方案是什么

我可以将condition移动到使用单个类和带有condition的方法分离
.jar
,在这里我生成该
.jar
的两个版本,并在应用程序启动时在类路径中切换这些版本吗JIT是否会在单独的
.jar
中删除对方法的调用,如果它发现该方法是空的

我可以通过在类路径中提供两个类来实现“ClassWithMyCondition”吗?其中一个类将有一个真正的实现,第二个类将只有空方法,并通过
class.forName
.newInstance()实例化其中一个
?JIT会从我的主循环嵌套方法中删除对empty方法的调用吗


解决这个问题最简单的字节码操作解决方案是什么?

执行这种逻辑的标准方法是为您想要的功能创建一个接口,然后为该功能创建两个(或更多)实现。只有一个实现将加载到您的运行时中,并且该实现可以做出它需要的假设,以便完全避免
if
情况


这样做的好处是每个实现都是互斥的,JIT编译器之类的东西可以忽略此特定运行的所有无用代码。

最简单的解决方案在这里工作。不要把事情过于复杂化

只要在某个地方放置一个不是编译时常量(如JLS中定义的)的
最终静态布尔值
,并在任何需要“条件”编译的地方引用它。JVM将在第一次看到它时对其进行评估,当代码得到JIT时,JVM将知道该值不会更改,然后可以删除该检查,如果该值为
false
,则删除该块


一些资料来源:Oracle有一个wiki页面,上面说在可能的情况下使用常量(请注意,在此上下文中,编译器是JVM/JIT,因此,
final
字段算作常量,即使根据JLS标准它不是编译时常量)。该页面链接到JIT所采用的方法,其中提到了诸如不断折叠和流敏感重写等技术,包括死代码删除。

您可以在命令行中传递自定义值,然后检查该值一次。因此,在您的代码中,有如下内容:

final static boolean customProp = "true".equalsIgnoreCase(System.getProperty("customProp"));
根据命令行参数,
static final
值将发生变化。这会将该值设置为
true

java -DcustomProp="true" -jar app.jar
这会将值设置为
false

java -jar app.jar
这提供了
静态最终布尔值的优点,但允许在不重新编译的情况下更改值


[编辑]


如注释所示,这种方法不允许在编译时进行优化。
静态最终布尔值
是在类加载时设置的,并且从此处保持不变。字节码的“正常”执行可能需要评估每个
if(customProp)
。然而,JIT发生在运行时,将字节码编译为本机代码。此时,由于字节码具有运行时值,因此可以进行更积极的优化,如内联或排除代码。请注意,您无法准确预测JIT是否会启动或何时启动。

您应该从属性文件加载该值,以避免每次启动时都需要重新编译。只需更新文本文件,在下一次程序运行时,它将使用新值。这是我很久以前写的一个例子:


每次运行代码时,JIT都会重新编译代码。不管你是否知道,你已经在做这件事了。这意味着,如果您有一个JIT认为没有更改的字段(甚至不必是最终字段),它将被内联,检查和代码将被优化


随着时间的推移,试图超越准时制越来越难。

你能给我一个理由否决这个吗?这个问题出了什么问题?你为什么需要完成这个?假设我有一个非常繁重的调试/日志逻辑(具体的图像表示算法结果等),我希望在发送给最终用户后能够打开和关闭。似乎他们不知道答案:)+1。到目前为止,这个问题很好。如果是这样,我将使用@rolfl选项和/或声明一个从配置文件加载值的常量。在这两种情况下,您都不需要重新编译整个应用程序。例如,JSF允许您通过
javax.faces.PROJECT_STAGE
context参数来实现这一点,该参数的值是
Development
Production
(还有其他值,但这两个值为您提供了思路)。但这违反了基本的干代码和重复代码。您的意思是我可以将内部if逻辑移动到其他实现,而JIT将删除对空方法的调用吗?DRY?不,想想java.util.List之类的东西。。。不是一个类在每个方法中都有一个条件,比如说
if(linked){do linked list things}或者{do array list things}
,而是有两个
list
的实现,
ArrayList
LinkedList
,你选择一个你想要的,如果
我完全同意,这应该通过多态性而不是
if
条件来实现+1A第二条注释,
java.util.List
的实际实现通常基于java.util.Abs