当前位置: 首页 > 知识库问答 >
问题:

如果一个带有while-true循环的方法只被调用一次,它将在线程的剩余生命周期中一直留在解释器中?

苗烈
2023-03-14

我有这样一种担心:如果一个方法包含一个while-true循环,它只被调用一次并被解释,那么它将永远在解释器中执行并降低性能。当我测试一个名为libminecraft 1.14.4的AOT编译的Minecraft版本时,我第一次怀疑这一点。我使用了OpenJDK13JVMCI,并看到了更好的峰值性能。我完全理解Minecraft有很多在多线程上运行的while-treal循环,所以当我用内联然后优化整个程序优化运行另一个测试时,除非AOT编译,否则它的性能非常糟糕(非优化版本在完全相同的OpenJDK版本的非AOT测试中表现良好)。如果一个带有while true循环的方法只被调用一次,那么它会在线程的剩余生命周期内留在解释器中,这是否真的是真的?我不能用-XX:PrintCompilation运行像Minecraft这样大的东西。

共有2个答案

黎浩然
2023-03-14

作为一般编程实践,而true循环不是一个好东西,或者最好尝试寻找一些替代方法。

解释器不存储任何代码,它只执行字节码,

这里的关键点是,只要线程入口函数不退出/返回,线程就会一直存在。然而,这并不一定意味着线程必须主动执行代码。

此外,还有各种实现while true循环的方法。如果您不想在中断条件出现之前执行一次,可以尝试使用< code > while(!idspnonenote)来实现。

阚亮
2023-03-14

具有长运行循环的方法也可以进行JIT编译。

热点 JVM 有一种称为堆栈上替换的技术:

也称为“OSR”。将解释的(或优化程度较低的)堆栈帧转换为编译的(或更优化的)堆栈框架的过程。当解释器发现一个方法正在循环时,就会发生这种情况,它要求编译器生成一个特殊的nmethod,在循环中的某个地方有一个入口点(特别是在向后分支),并将控制权转移到该nmethod。

大多数编译器特性/优化对OSR编译有效,就像对常规编译一样。然而,在有些情况下(1,2),OSR存根看起来不如完全编译的方法优化。但是在实际应用中,长时间运行的循环不调用其他方法的情况并不常见,所以OSR很少是性能问题。

 类似资料:
  • 我试图用Java实现一个简单的客户机-服务器应用程序。 这是代码: 客户端.java 服务器.java 这是主要类: 代码的逻辑很简单:客户端和服务器都在等待< code>while(true)循环中的消息。 服务器的< code>listen方法中的< code>while循环执行得很好。但是,在< code>listenForMessages方法中,循环似乎只执行一次。我只看到一个“在循环”印

  • //基本上我需要提示用户输入等级,并计算A的B的数量等等。我不知道如何让循环在每个用户输入中循环一次。它只是垃圾邮件输入考试成绩。编辑谢谢大家的帮助我想通了! }

  • 本文向大家介绍请解释一下JSP的生命周期,包括了请解释一下JSP的生命周期的使用技巧和注意事项,需要的朋友参考一下 JSP生命周期定义为从创建到破坏的整个过程。这类似于Servlet生命周期,但需要一个额外的步骤才能将JSP编译为Servlet。 JSP遵循的路径 以下是JSP遵循的路径- 汇编 初始化 执行 清理 JSP生命周期的四个主要阶段与Servlet生命周期非常相似。以下描述了四个阶段-

  • 我有一个类(称为name),它有如下不同的方法: alex(), john(), claire(), charles(), luke(), richard(), jen()等等 我需要逐一调用所有这些方法,例如: ... 等等 我尝试的是创建一个名称列表,并调用循环中的所有方法 但这种调用方法的方式正在失败。有没有办法在循环中调用同一类的多个方法?

  • 问题内容: 我有以下结构: 该方法 可以 被许多线程同时调用。该 会 抛出异常(它在后台,可能成为过时的使用一些数据)。 如果引发异常,则执行一些耗时的任务,比如说“更新”所有当前数据,并且我可以调用。 问题: 如何确保只调用 一次 ?如果我在的条目中放置了原子标志,则不能确定何时清除该标志。 我该如何解决?请注意:由于它是一个外部API,因此我无法修改,并且我正在使用装饰器模式来使用它。 问题答

  • 问题在代码的注释中,很抱歉,我认为它更整洁,因为流程很重要,我想。。。 //*这是来自Oracle:(https://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html#hasNextInt()) ”hasNextInt 公共布尔值hasnetint() 如果此扫描仪输入中的下一个标记可以使用nextInt()方法解释为默认基数中的in