0

我正在尝试将 ASM 用于我的项目并遇到性能问题,我试图使用静态方法获取所需的对象,并且它被调用了 1000 次

visitor.visitMethodInsn(Opcodes.INVOKESTATIC, TrackingConstants.TO_HELPER_CLASS, "getRTTDObject",TrackingConstants.TO_HELPER_GET_CLIENT_METHOD_DESC);

visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, TrackingConstants.CLIENT_INTERFACE_CLASS, "getPattern",TrackingConstants.CLIENT_INTERFACE_CLASS_GETPATTERN_METHOD_DESC);     

第一次调用导致了我的开销(我得到所需的对象并传递到下一行以对对象执行“getPattern”。在调查期间,我意识到我试图通过静态方法检索的对象可以从启动自己所以如果我能够将该Java对象推入堆栈并避免静态调用我不会遇到任何性能问题

我尝试了几种没有运气的方法最后尝试创建对象的新字段但得到一个IllegalArgumentException 类似于这篇文章 Creating a new field with asm 4在通过链接后我意识到我们需要编写代码来创建对象并且不能直接使用现有对象。

那么有没有办法我可以将现有的 Java 对象加载到堆栈上(我猜它已经在堆栈上,有没有办法可以使用它)并执行所需的操作而不是使用静态调用来获取它?有没有办法可以实现它?

4

1 回答 1

1

一旦对象在堆栈上(大概是在您第一次调用静态方法之后),您可以:

  1. DUP每次需要时,发出一条指令以复制堆栈中已经存在的值。这可能是性能最高的选项,但它要求您以这样一种方式制作字节码,以便在需要时该值始终位于/接近堆栈的顶部。该指令有几种变体DUP可供选择,每种变体都有不同的行为;有关详细信息,请参阅JVM 规范 §6.5

  2. 调用一次静态方法,然后将结果存储在临时变量中(使用ASTORE指令变体之一)。在需要时使用相应的ALOAD变体将其压入堆栈。

根据您的方法的结构,您还可以组合这些技术(从临时本地加载,DUP必要时做一些不相关的事情,重复等)。

于 2013-10-11T16:26:57.387 回答