首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >JVM字节码中的NOP是做什么用的?

JVM字节码中的NOP是做什么用的?
EN

Stack Overflow用户
提问于 2012-05-03 05:36:08
回答 3查看 4.7K关注 0票数 18

Java Virtual Machine的NOP操作码在今天的Java虚拟机中有什么实际用途吗?如果是这样,在字节码中生成NOP的场景是什么?

我甚至有兴趣看到一个用NOP编译成字节码的Java代码示例。

更新

BCEL的MethodGen类说,

在生成代码时,可能需要插入

操作。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-05-03 22:19:46

一些NOP字节码使用案例用于class文件转换、优化和由Apache BCELASMFindBugsPMD等工具执行的静态分析。Apache BCEL manual涉及到NOP的一些用途,用于分析和优化目的。

虚拟机可以使用NOP字节码进行即时优化,以确保处于同步安全点的代码块被正确对齐,从而避免false sharing

至于一些使用包含NOP字节码的JDK javac编译器编译的示例代码,这是一个有趣的挑战。但是,我怀疑编译器是否会生成任何包含the bytecode instruction stream is only single-byte aligned之后的NOP字节码的class文件。我很好奇能看到这样的例子,但我自己想不出任何例子。

票数 12
EN

Stack Overflow用户

发布于 2015-10-23 02:56:52

下面是我一直在研究的一些代码中的一个示例,其中nop指令被放入字节码中(正如Eclipse的字节码Visualizer所看到的那样)。

原始代码

代码语言:javascript
复制
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)));
  }
}

equals(Object)方法的转换后的字节代码

代码语言:javascript
复制
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;
}

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

票数 2
EN

Stack Overflow用户

发布于 2012-05-03 06:19:06

通常不会为处理器流水线优化添加任何操作。我不确定Java目前在多大程度上使用它们。

来自Wikipedia

最常用于计时目的,强制内存对齐,防止危险,占用分支延迟槽,或用作稍后在程序开发中由活动指令替换的占位符(或在重构有问题或耗时时替换移除的指令)。在某些情况下,NOP可能有轻微的副作用;例如,在摩托罗拉68000系列处理器上,NOP操作码会导致流水线的同步。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10422086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档