Java JVM字节码中的NOP用于什么?

Java JVM字节码中的NOP用于什么?,java,jvm,bytecode,nop,Java,Jvm,Bytecode,Nop,Java虚拟机的NOP操作码在今天的JVM中有什么实际用途吗?如果是,在哪些情况下,NOPs将以字节码生成 我甚至有兴趣看到一个Java代码的例子,它用NOPs编译成字节码 更新 BCEL的班级说 生成代码时,可能需要插入NOP操作 我猜其他字节码生成库也在同一条船上,正如公认的答案所指出的那样。处理器管道优化通常不添加操作。我不确定Java目前在多大程度上使用它们 发件人: NOP最常用于定时目的,以强制内存 对齐,以防止危险,占用分支延迟槽,或作为 稍后在程序中用激活的说明替换支架 开发(

Java虚拟机的
NOP
操作码在今天的JVM中有什么实际用途吗?如果是,在哪些情况下,
NOP
s将以字节码生成

我甚至有兴趣看到一个Java代码的例子,它用
NOP
s编译成字节码


更新

BCEL的班级说

生成代码时,可能需要插入NOP操作


我猜其他字节码生成库也在同一条船上,正如公认的答案所指出的那样。

处理器管道优化通常不添加操作。我不确定Java目前在多大程度上使用它们

发件人:

NOP最常用于定时目的,以强制内存 对齐,以防止危险,占用分支延迟槽,或作为 稍后在程序中用激活的说明替换支架 开发(或在需要重构时替换删除的指令) 有问题或耗时)。在某些情况下,NOP可能有轻微的 副作用;例如,在摩托罗拉68000系列处理器上, NOP操作码导致管道同步


一些
NOP
字节码用例用于
class
文件转换、优化和静态分析,这些都是由、、等工具执行的。Apache涉及到
NOP
在分析和优化方面的一些用途

JVM可以使用
NOP
字节码进行JIT优化,以确保位于同步安全点的代码块正确对齐以避免错误


对于一些使用JDK
javac
编译器编译的包含
NOP
字节码的示例代码,这是一个有趣的挑战。但是,我怀疑编译器是否会生成任何包含
NOP
字节码的
class
文件。我很想看到这样一个例子,但我自己想不出任何例子。

这里是一个我一直在编写的代码示例,其中包含nop指令 放置在字节码中的位置(由Eclipse字节码可视化工具查看)

原始代码

public abstract class Wrapper<T extends Wrapper<T,E>,E>
  implements Supplier<Optional<E>>, Consumer<E>
{
  /** The wrapped object. */
  protected Optional<E> inner;

  /*
   * (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  /**
   * A basic equals method that will compare the wrapped object to
   * whatever you throw at it, whether it is wrapped or not.
   */
  @Override
  public boolean equals(final Object that)
  {
    return this==that
        ||LambdaUtils.castAndMap(that,Wrapper.class,afterCast
            -> inner.equals(afterCast.inner))
        .orElseGet(()
            -> LambdaUtils.castAndMap(that,Optional.class,afterCast
                -> inner.equals(afterCast))
            .orElseGet(()
                -> Optional.ofNullable(that).map(thatobj
                    -> that.equals(inner.get()))
                .orElseGet(()
                    -> false)));
  }
}

我不知道为什么要插入这些内容。我只是希望它们不会对性能产生负面影响。

通常在调试代码中使用它,以允许在某些不能转换为字节码的内容上设置断点,如
{
。你的意思是当用
javac-g
编译Java文件时,这会出现在字节码中吗?我不相信
javac
会做到这一点。但是其他编译器和调试器可以利用这一功能。例如,使用烟尘生成带有一些if语句的简单代码会导致NOPs。这在物理m中是有意义的achine操作码,但是对于虚拟机操作码来说,这样的东西有什么用呢?我很感激这个答案,但是这个问题是关于JVM的。没有
nop
s,这只是您使用的字节码可视化工具中的一个bug。
invokedynamic
指令由五个字节组成,最后两个字节是零pe显然,字节码可视化工具不知道这一点,并且假设
invokedynamic
指令只有三个字节,并将两个零字节误解为
nop
指令。请看。我想这是有意义的。我正在等待Eclipse Neon字节码可视化工具的更新。也许我们应该告诉de显影剂。
public boolean equals(java.lang.Object arg0) {
    /* L27 */
    0 aload_0;                /* this */
    1 aload_1;                /* that */
    2 if_acmpeq 36;
    /* L28 */
    5 aload_1;                /* that */
    6 ldc 1;
    8 aload_0;                /* this */
    9 invokedynamic 29;       /* java.util.function.Function apply(ext.cat.wcutils.collections.Wrapper arg0) */
    12 nop;
    13 nop;
    14 invokestatic 30;       /* java.util.Optional ext.cat.wcutils.util.LambdaUtils.castAndMap(java.lang.Object arg0, java.lang.Class arg1, java.util.function.Function arg2) */
    /* L30 */
    17 aload_0;               /* this */
    18 aload_1;               /* that */
    19 invokedynamic 39;      /* java.util.function.Supplier get(ext.cat.wcutils.collections.Wrapper arg0, java.lang.Object arg1) */
    22 nop;
    23 nop;
    24 invokevirtual 40;      /* java.lang.Object orElseGet(java.util.function.Supplier arg0) */
    27 checkcast 46;          /* java.lang.Boolean */
    30 invokevirtual 48;      /* boolean booleanValue() */
    /* L37 */
    33 ifne 5;
    /* L27 */
    36 iconst_0;
    37 ireturn;
    38 iconst_1;
    39 ireturn;
}