草庐IT

java - jvm +LogCompilation输出中 "callee is too large"的含义

所以在+LogCompilation的输出中打印了消息calleeistoolarge和toobig与特定方法相关联(以及编译器决定不内联)。但是“被调用者”不是方法本身吗?这还有什么意思?如果是这样,“calleetoolarge”和“toobig”之间的区别是什么——它们的意思不一样吗(也许这只是一条遗留的日志消息,2位工程师对同一件事使用不同的语言?)或者“callee”是否真的意味着“caller”?不内联的任何一个理由都是合理的。我有点不好意思,我不明白这一点。 最佳答案 HotSpotJVM有两个JIT编译器:C1和C2

java - 使用 JIT 编译器的 Collections.emptyList 和空 ArrayList 的性能

使用Collections.emptyList()或空的ArrayList之间是否存在性能差异,尤其是在使用JIT编译器时?我可以想象-例如-JIT编译器不会执行内联或静态方法调用,因为执行的方法取决于类型。编辑我知道Collections.emptyList()返回一个不可变列表,而ArrayList是可变对象。我的意思是,如果我将一个或另一个作为参数传递给方法并且该方法不修改列表,是否会限制JIT编译器优化该方法的可能性?一个简单的例子(只是为了阐明我的意思):intsum(Listlist){intsum=0;for(inti=0;i如果我只使用ArrayList调用此方法,JI

java - 类文件格式的最终​​变量

class文件格式是否支持final关键字以防与变量一起使用?或者它只是从代码中推断出变量的有效终结性,然后JIT编译器基于它执行优化?Here,在类文件格式文档中,他们提到了final关键字,但仅限于将它与finalblock和finalclass一起使用的情况。没有关于最终变量的内容。 最佳答案 不,类文件中没有编码的此类信息。您可以通过使用final局部变量和不使用final编译源文件来轻松验证这一点-结果类将是相同的。但是,Java8添加了MethodParameters记录有关方法参数的名称和访问标志的信息的属性。这意味着

java - 即时编译——什么时候在 Java 中实际发生?

最近我参加了一个关于Java效率的讨论。正如我所听到的,许多反对Java的论点是解释“非常耗时”,正因为如此,即使是简单的Java程序运行起来也比直接编译为机器代码的类似程序慢得多。对此的回答是,Java代码通常直接编译为机器代码,如果只有JVM计算,它会使程序比以标准方式解释时更快。我的问题是:JVM什么时候真正“决定”执行即时编译?使JIT比标准字节码解释更有效的标准是什么?我的意思是,编译本身需要一些时间,据我所知,这一切都应该在程序已经运行时发生? 最佳答案 这根据您的JVM及其设置而有很大差异。维基百科:Forexampl

java - 智能 JVM 和 JIT 微优化

随着时间的推移,Sun的JVM和JIT变得非常智能。不再需要过去作为必要的微优化而成为常识的事情,因为它会为您处理。例如,过去的情况是您应该将所有可能的类标记为最终类,以便JVM内联尽可能多的代码。但是现在,JIT会根据运行时加载的类来知道您的类是否是最终类,如果您加载一个类以使原始类成为非最终类,它会取消内联方法并将其取消标记为final。JVM或JIT还为您做了哪些其他智能微优化?编辑:我将其设为社区维基;我想随着时间的推移收集这些。 最佳答案 这太令人印象深刻了。所有这些都是您在C++中不能做的事情(当然在Java中做不到)。

java - 玩框架。无需编译

有人向我介绍了Play框架,我发现其中一个令人惊奇的事情是不需要编译项目。您只需要保存编辑的文件并重新加载网页。我被告知Java源代码被编译为字节码,然后用JIT编译器编译,那么Play框架内部有什么神奇之处? 最佳答案 在DEV模式下运行时,Play的工作方式是检查java文件的最后修改日期,并将它们与运行时生成的.class文件进行交叉引用。如果它识别出某些内容已更改,则会在运行时重新编译它们。在Play1.x中-重新编译是使用eclipsejdt编译器(org.eclipse.jdt.internal.compiler.Com

java - JIT 自动内联的方法的大小是多少?

我听说JIT会自动内联小方法,例如getter(它们大约有5个字节)。边界是什么?有没有JVM标志? 最佳答案 HotSpotJIT内联策略相当复杂。它涉及许多启发式方法,例如调用方方法大小、被调用方方法大小、IR节点计数、内联深度、调用计数、调用站点计数、抛出计数、方法签名等。访问器方法(getters/setters)和普通方法(字节码数少于6)跳过了一些限制。相关源码大部分在bytecodeInfo.cpp.请参阅InlineTree::try_to_inline、should_inline、should_not_inline

java - 如何反编译Java中的volatile变量?

我听说volatile关键字可以在变量的写操作之前添加内存屏障。所以我写了代码:publicclassTest{privateObjecto;publicTest(){this.o=newObject();}privatevolatilestaticTestt;publicstaticvoidcreateInstance(){t=newTest();//volatilewouldinsertmemorybarrierhere.}publicstaticvoidmain(String[]args)throwsException{Test.createInstance();}}然后反编译:

java - 我应该查看 java 编译器生成的字节码吗?

没有JIT编译器可能会将字节码“转换”成完全不同的东西。它将导致您进行过早的优化。是你不知道哪些方法会被JIT编译,所以最好把它们都优化一下。它会让你成为更好的Java程序员。我是在不知道(显然)的情况下问的,所以请随意重定向到JIT超链接。 最佳答案 是的,但在某种程度上——作为一个了解幕后情况的教育机会是很好的,但可能应该适度进行。这可能是一件好事,因为查看字节码可能有助于理解Java源代码将如何编译成Java字节码。此外,它可能会给出一些关于编译器将执行哪种优化的想法,以及可能对编译器可以执行的优化量的一些限制。例如,如果执行

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

我正在寻找一种方法来为if条件。当然,每次应用程序运行时,此条件只会更改一次-在启动时。我知道可以有条件地编译“条件下的编译时常量”,并且可以从代码中删除整个条件。但是,无需重新编译源代码的最快(并且可能最简单)的替代方案是什么?我可以移动条件以将.jar与带有条件的单个类和方法分开,在那里我生成该.jar的两个版本并将这些版本切换到类路径中应用程序启动?JIT是否会在单独的.jar中删除对方法的调用如果它发现该方法是空的?我能否通过在实现“ClassWithMyCondition”的类路径中提供两个类来做到这一点,其中一个类将有一个真正的实现,第二个将只有空方法并通过Class.fo