class檔案結構[5] 區域性變量表的槽位複用及其對垃圾回收的影響
long、double型別在區域性變量表中需要佔用2個槽位
其他型別如int、引用型別需要佔用1個槽位
非static的成員方法的第一個區域性變數都是this引用
以上一節的例子為例
一共佔用5個槽位,其中
D(double)型別的arg1佔用2 槽位,其餘各佔用1個槽位。
區域性變量表中的槽位是可以複用的
如果一個區域性變數過了其作用範圍,那麼在其作用範圍後申明的新的區域性變數,就有可能複用過期的區域性變數的槽位,從而達到節省資源的目的。
以如下程式碼為例
Java Code
1 |
package com.test.a; int b=a; System.out.println(b); } int c=0; int d=0; } } |
method1()的區域性變量表佔用3個槽位,其中this佔用1個,a、b各佔用一個
method2的區域性變量表佔用2個槽位,雖然也擁有this、a、b 3個區域性變數,但是b複用了a的槽位,他們都佔用的第1個槽位
同理,method3的區域性變量表佔用3個槽位,c、d分別複用了迴圈語句中的a
在執行階段,.class檔案中的區域性變量表會被使用到棧幀的區域性變量表中
後面會講到,被棧幀的區域性變量表直接或間接引用到的物件,在垃圾回收時是不會被回收的
槽位複用也會影響到垃圾回收,以如下程式碼為例,執行時使用-XX:+PrintGC引數
Java Code
1 |
package com.test.b; |
在method1()中,在垃圾回收前先將a置null,使byte陣列失去被引用,故可以順利回收byte陣列
在method2()中,雖然a已經離開了作用範圍,但是a仍然存在於棧幀的區域性變量表中,並且引用byte陣列,故byte陣列還不能被回收
在method3()中,區域性變數b會複用a的槽位
在垃圾回收前,申明瞭變數b來複用a的槽位,此時棧幀的區域性變量表中沒有引用byte陣列,故能夠順利回收byte陣列