Java虛擬機垃圾收集算法

Java虛擬機的內存區域中,程序計數器、虛擬機棧和本地方法棧三個區域是線程私有的,隨線程生而生,隨線程滅而滅;棧中的棧幀隨着方法的進入和退出而進行入棧和出棧操作,每個棧幀中分配多少內存基本上是在類結構確定下來時就已知的,因此這三個區域的內存分配和回收都具有確定性。垃圾回收重點關注的是堆和方法區部分的內存。以下是小編爲大家搜索整理的Java虛擬機垃圾收集算法,希望能給大家帶來幫助,更多精彩內容請及時關注我們應屆畢業生考試網!

Java虛擬機垃圾收集算法

  一 標記-清除算法(Mark-Sweep)

首先標記出所有需要回收的對象,標記完成後統一回收。

主要缺點: 1. 標記和清除效率都很低 2. 產生大量不連續的內存碎片,導致後面分配大內存空間失敗

  二 複製算法

將可用內存劃分爲大小相等的兩塊, 每次只使用其中一塊。 當這塊用完後,就將還存活對象複製到另外一塊上面,再把已經使用的內存空間一次清理掉。

主要缺點: 代價太高,至少一半的內存不能使用。

  三 標記-整理算法

標記過程和標記-清除算法一致,但是後續步驟是讓所有存活的對象都向一端移動,然後清理掉邊界以外的內存。

  四 分代收集算法

當前商業虛擬機都採用此算法,分爲不同對象代,去進行不同管理。

  【相關閱讀】

  什麼是java位運算

位運算允許對整數中的單個比特進行操作。位運算會對連個操作數中對應的比特執行布爾代數運算,併產生一個結果。

java中有3種位運算符:&(與) |(或) ^(異或) ~(非)

看例子說明位運算的過程:

public class test{

public static void main(String[] args){

int a=12|2; //1100|0010

tln(a);

}

}

結果是14(1110)

位移運算操作的目標也是數字的.二進制的位。用來操作位數的向左向右移動。

java種有3種基本的位移操作:

>>(右移) <<(左移) >>>(無符號右移)

<<:將操作符左邊的整數按位向左邊移動運算符右邊整數指定的位數,在右邊添加0;

看例子:

public class test{

public static void main(String[] args){

int a=8<<1;

tln(a);

}

}

8的二進制表示:00000000 00000000 00000000 00001000

左移1位後二進制:00000000 00000000 00000000 00010000 -> 14

結果爲14

tip:左移相當於num*(2^n) 其中num爲被移數,n爲移動的位數

>>:右移的道理也是一樣的,注意的是:若最高位爲1,移動後最高位用1來填充,否則用0來填充。

例子:

int a=-8>>1;

tln(a);

-8的二進制:11111111 11111111 11111111 11111000

右移後的二進制:11111111 11111111 11111111 11111100 -> -4

結果爲-4

tip:右移相當於num/(2^n) 其中num爲被移數,n爲移動的位數

>>>:無符號右移跟右移原理是一樣的,只是覆蓋位的覆蓋規則不同:不管最高位是0還是1,全部用0來填充。

例子:

int a=-8>>>1;

tln(a);

-8的二進制:11111111 11111111 11111111 11111000

無符號右移後的二進制:01111111 11111111 11111111 11111100 -> 2147483644

tip:用無符號右移的時候要注意,絕對值很小的負數移動後都可能成爲絕對值很大的正數,這在大多數情況下沒意義。

奇葩的例外:

那代碼:

int a=11>>32;

long b=12<<64;

tln(a);

tln(b);

int類型佔32位,long類型佔64位,這樣子的話,上面的例子輸出應該都是0纔對,因爲剛好將有效位都移走了,但結果並不是這樣的。

輸出的結果是:11 12

這跟java對位移的底層操作機制有關:

從結果可以看出兩個數都沒有變化,這是因爲,在進行移位前,java首先將要移動的位數跟被移數的位數求餘,然後去移動餘數個位數。上面例子中,32對32求餘,64對64求餘,結果都是0,java系統對被移數進行0個位的移動,也就是沒移動啦。

這樣子的話,看下下面的代碼:

int c=8>>33;

tln(c);

因爲int有32位,那麼8實際上被移動的位數是:332=1;

就相當於:int c=8>>1;

結果自然是:4