2013-10-07 49 views
0

加載現有的Java對象到堆棧我想使用ASM爲我的項目,打在那裏我試圖用靜態方法和其所謂像1000次,獲得所需的對象性能問題使用ASM

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對象推入堆棧並避免靜態調用,我不會面臨任何性能問題。所以,如果我能夠將該Java對象推入堆棧,並且不會遇到任何性能問題,那麼我嘗試了幾種方法運氣和最後嘗試創建對象的新領域,但得到一個IllegalArgumentException類似於這篇文章 Creating a new field with asm 4通過鏈接後,我意識到,我們需要編寫代碼來創建對象,不能直接使用現有的對象。

那麼是否沒有辦法可以將我現有的Java對象加載到堆棧上(我猜它已經在堆棧上了,是否有一種方法可以使用它)並執行所需的操作而不是使用靜態調用來獲取它?有沒有辦法實現它?

+0

您是否確定這實際上是性能瓶頸?你有沒有確定JVM不緩存/內聯已經? – Antimony

+0

嗨銻,不,我使用探查器來確定瓶頸在哪裏,並發現靜態調用正在消耗大約1.8%。如何知道緩存/內聯是否完成?您的意思是這些重複的靜態調用需要緩存和這應該由JVM照顧? – VishwanathB

+0

JVM應該自動執行這樣的事情。不知道爲什麼它不在這種情況下。 – Antimony

回答

1

一旦對象是堆棧(後想必你打電話給你靜態方法第一次),您可以:

  1. 發出DUP指令給每個是時間已經複製堆棧上的價值需要。這可能是性能最高的選項,但它需要您設計字節碼,以便在您需要時,該值始終位於堆棧的頂部/附近。有幾種DUP指令可供選擇,每種指令都有不同的行爲;詳情請參閱JVM Specification §6.5

  2. 調用一次靜態方法,然後將結果存儲在臨時變量中(使用ASTORE指令變體之一)。當需要時,使用相應的ALOAD變體將其推入堆棧。

根據您的方法的結構,你也可以(從臨時的地方,DUP必要的負荷,做一些無關的,重複等)結合這些技術。