2012-11-10 71 views
0

考慮從兩行代碼:由javap的產生的字符串返回)和它的字節碼解釋

... 
rs.next(); //rs is ResultSet interface. 
rs.getString("name"); 
... 

字節碼是:

... 
35: invokeinterface #9, 1; //InterfaceMethod java/sql/ResultSet.next:()Z 
    40: pop 
    41: aload 4 
    43: ldc  #10; //String name 
    45: invokeinterface #11, 2; //InterfaceMethod java/sql/ResultSet.getString: 
(Ljava/lang/String;)Ljava/lang/String; 
    50: pop 
    51: aload_2 
    52: invokeinterface #12, 1; //InterfaceMethod java/sql/Connection.close:()V 

... 

我試圖解釋這個字節碼。

對於線rs.getString("name");字節碼從管線43開始51.

1)在管線45方法調用並且如Ljava /郎/ String.Is這個右表示返回字符串對象OR這裏,只有方法正在從索引#11 TO STACK的常量池加載並在第50行執行?

2)rs.getString("name");返回的字符串對象在哪裏?在堆棧或堆上,因爲我認爲aload_2正在推動堆棧的某些價值。

其實在這裏,我很困惑在以下幾點:

如果假設我有:

... 
rs.next(); 
rs.getString("name"); 
rs.getString("name"); 
rs.getString("name"); 
rs.getString("name"); 
...10 more times... 
... 

都將返回一個相同的名字。然後會有10個不同的字符串對象具有相同的值。所以它會浪費內存,並且是使用intern()的情況。但是,如果這些將在堆棧上,那麼它仍然會被視爲內存浪費,並需要intern()?

3)我認爲由rs.getString("name");返回的字符串對象不是一個interned字符串,所以絕對不會在永久代存儲區?

回答

2

字節碼的用於呼叫

rs.getString("name") 

相關部分是

41: aload 4 
43: ldc  #10; //String name 
45: invokeinterface #11, 2; //InterfaceMethod java/sql/ResultSet.getString:(Ljava/lang/String;)Ljava/lang/String; 
50: pop 

採取這一行一個操作碼在時間:

41: aload 4 

推存儲在本地對象變量#4(rs)放入堆棧

43: ldc  #10; //String name 

推動字符串常量"name"到堆棧

45: invokeinterface #11, 2; //InterfaceMethod java/sql/ResultSet.getString:(Ljava/lang/String;)Ljava/lang/String; 

彈出頂部2項從棧調用接口方法java/sql/ResultSet.getString:(Ljava/lang/String;)Ljava/lang/String;並推動結果(Ljava/lang/String;)壓入堆棧。

50: pop 

然後將結果從先前的方法從堆棧中彈出。

+0

謝謝喬納森!在彈出第50行的結果後,結果(一個字符串對象)將被垃圾收集? –

+0

我已經問了關於我上面的評論的其他問題在'http:// stackoverflow.com/questions/13321863/java-stack-and-object-returned-a-a method.' –