【发布时间】:2015-04-30 23:00:00
【问题描述】:
我正在尝试在我的项目中使用 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 对象加载到堆栈上(我猜它已经在堆栈上,有没有办法可以使用它)并执行所需的操作而不是使用静态调用来获取它?有什么方法可以实现吗?
【问题讨论】:
-
您确定这实际上是一个性能瓶颈吗?您确定 JVM 没有缓存/内联它吗?
-
嗨锑,不,我使用分析器来确定瓶颈在哪里,发现正在进行的静态调用消耗了大约 1.8%。我怎么知道缓存/内联是否完成?你的意思是这些重复静态调用需要缓存,这应该由 JVM 处理??
-
那么 JVM 应该自动执行类似的操作。不知道为什么在这种情况下不是。
-
我将与我认识的一些 JVM 人员核实一下。回到我的问题,所以我无法加载现有的 java 对象以避免静态调用??我的方法适配器中有一个 getter 方法这给了我 java 对象.. 有一种方法可以将它加载到我正在尝试使用 ASM 填充的当前堆栈中吗?我从您之前的回复中得知 visitLdcInsn 不会在这里工作...
-
获取现有非常量对象的唯一方法是通过方法调用或字段访问。但如果方法或字段足够简单,无论如何都应该内联。
标签: java bytecode java-bytecode-asm bytecode-manipulation