1. 程式人生 > >class檔案結構[5] 區域性變量表的槽位複用及其對垃圾回收的影響

class檔案結構[5] 區域性變量表的槽位複用及其對垃圾回收的影響

longdouble型別在區域性變量表中需要佔用2個槽位

其他型別如int、引用型別需要佔用1個槽位

static的成員方法的第一個區域性變數都是this引用

以上一節的例子為例


一共佔用5個槽位,其中

Ddouble)型別的arg1佔用2 槽位,其餘各佔用1個槽位。

區域性變量表中的槽位是可以複用的

如果一個區域性變數過了其作用範圍,那麼在其作用範圍後申明的新的區域性變數,就有可能複用過期的區域性變數的槽位,從而達到節省資源的目的。

以如下程式碼為例

 Java Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

package com.test.a;

publicclass Test{
    
    
publicvoid method1(){
        
int a=0;
        System.out.println(a);
        
int b=0;
    }
    
    
publicvoid method2(){
        {
            
int a=0;
            System.out.println(a);
        }
        
        
int b=0;
    }
    
    
publicvoid method3(){
        

for(int a=0; a<100; a++){
            
int b=a;
            System.out.println(b);
        }
        
        
int c=0;
        
int d=0;
    }
}

method1()的區域性變量表佔用3個槽位,其中this佔用1個,ab各佔用一個

 

method2的區域性變量表佔用2個槽位,雖然也擁有thisab 3個區域性變數,但是b複用了a的槽位,他們都佔用的第1個槽位

 

同理,method3的區域性變量表佔用3個槽位,cd分別複用了迴圈語句中的a

b的槽位

 

在執行階段,.class檔案中的區域性變量表會被使用到棧幀的區域性變量表

後面會講到,被棧幀的區域性變量表直接或間接引用到的物件,在垃圾回收時是不會被回收的

槽位複用也會影響到垃圾回收,以如下程式碼為例,執行時使用-XX:+PrintGC引數

 Java Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

package com.test.b;

publicclass Test{
    
    
publicvoid method1(){
        
byte[] a=newbyte[5*1024*1024];
        a=null;
        System.gc();
    }
    
    
publicvoid method2(){
        {
            
byte[] a=newbyte[5*1024*1024];
            System.out.println(a.length);
        }
        System.gc();
    }
    
    
publicvoid method3(){
        {
            
byte[] a=newbyte[5*1024*1024];
            System.out.println(a.length);
        }
        
int b=0;
        System.gc();
    }
}

method1()中,在垃圾回收前先將anull,使byte陣列失去被引用,故可以順利回收byte陣列

method2()中,雖然a已經離開了作用範圍,但是a仍然存在於棧幀的區域性變量表中,並且引用byte陣列,故byte陣列還不能被回收

 

method3()中,區域性變數b會複用a的槽位


在垃圾回收前,申明瞭變數b來複用a的槽位,此時棧幀的區域性變量表中沒有引用byte陣列,故能夠順利回收byte陣列