每天資訊Java中有GC就是爽,再也不用自己清理垃圾了

菜單

Java中有GC就是爽,再也不用自己清理垃圾了

Java中有GC就是爽,再也不用自己清理垃圾了

Java中的“GC”是什麼呢?

它的英文是Garbage Collection,翻譯過來就是

垃圾回收

,是JVM用來幫你回收Java程式中產生的垃圾的一種機制。

對於Java工程師(碼農)來說,瞭解垃圾回收機制(GC)有哪些好處呢?

首先,可以裝逼,哦,不不,可以滿足Java工程師(碼農)求知慾;其次,可以幫你寫出更好的Java應用程式。

想了解GC,你得先了解它們:

首先,來看JVM在執行時的記憶體圖:

Java中有GC就是爽,再也不用自己清理垃圾了

這裡呢,咱們只說說

堆記憶體

棧記憶體

Java中有GC就是爽,再也不用自己清理垃圾了

堆記憶體

:Java 中的堆是 JVM 所管理的最大的一塊記憶體空間,主要用於存放各種類的例項物件。你也可以這麼理解:

它是管理物件的,凡是new出來的物件,都在堆記憶體裡

這塊記憶體呢,是可以調配大小的,這裡有引數:

-Xms:設定JVM啟動時最小的堆記憶體大小

-Xmx:設定JVM堆的最大記憶體大小

棧記憶體:

一些基本型別的變數和物件的引用變數都是在函式的棧記憶體中分配。透過這個引數可以調配它的大小,

-Xss:這個引數就是用來指定棧的大小

這裡咱們舉個例子再來說明堆和棧,假如有這樣兩句話:

int i=10;

LovoStudent s = new LovoStudent();

它們在JVM的記憶體中如何分配呢?看圖:

Java中有GC就是爽,再也不用自己清理垃圾了

為何讓大家看記憶體圖呢?是為了說明什麼是Java中的垃圾。那這個垃圾到底是什麼呢?

你可以這麼理解,凡是

不被引用變數引用的物件都是垃圾

哦豁,什麼意思,自己去揣摩10分鐘。揣摩完回來,咱們拿上面的例子來說,還是這句話,LovoStudent s = new LovoStudent();

我把這個堆記憶體中的new LovoStudent();變成垃圾怎麼來寫?

直接寫 s=null;引用變數不再引用堆記憶體的物件,那這個物件就是垃圾。

Java中有GC就是爽,再也不用自己清理垃圾了

那麼我問個智障問題,咱們所說的垃圾,會存在於JVM中哪塊記憶體裡?

垃圾回收

明白了以上的內容,垃圾回收原理就很容易理解了。

垃圾回收機制就是JVM根據一定的演算法和執行緒排程(這裡只做簡單認識,感興趣的關注朗沃部落格,後續有文章會詳解哪些演算法和執行緒排程)來處理產生的垃圾。這種機制對程式設計師來說,你不用手動釋放記憶體,也不用擔心記憶體洩漏問題。在其它語言中,比如C,手動釋放記憶體很蛋疼吶!

說到回收,不得不提Object類中的finalize()方法,當垃圾回收器確定不存在對該物件的更多引用時,由物件的垃圾回收器呼叫此方法。也就是說當一個物件被當作垃圾回收時,會呼叫該方法。既然如此,那咱們是不是可以寫個類繼承一下Object(廢話,你能寫個類不繼承自Object麼),覆寫finalize(),比如寫個輸出語句:

System。out。println(“我成垃圾了,正在被回收”);來顯式的看一看物件什麼時候被回收的呢?完全可以。說完這個finalize()方法,還得說說System。gc()方法,這個方法又是幹嘛的?執行垃圾回收器。呼叫 gc 方法意味著JVM做了一些努力(注意是一些努力,並不是100%,通常還是能回收的)來回收未用物件,以便能夠快速地重用這些物件當前佔用的記憶體。

說完這些前提,咱們就可以設個場景:

假如你去飯館吃飯,首先得佔個桌子,佔了桌子之後呢就點菜上菜,假設你是土豪,可以點很多菜,陸續上來,先上的菜一來,你一頓的胡吃海塞留下很多垃圾,後來的菜再來,可能沒地方放。開飯館的肯定考慮這個問題啊,畢竟顧客是上帝嘛,於是安排了個服務員小妹兒,不定時的在場子裡巡迴,來收走你吃完菜的盤子。好像這問題就解決了,但是,不排除你是個吃貨,吃的太快了,小妹兒來不及巡迴到你這兒,你就有很多垃圾了,此時你是不是得大喊一聲,“哎,小妹兒,到這兒收空盤子”,然後小妹兒對你微微一笑,“好的,我馬上來收”

是這樣子,

飯館——JVM

桌子——堆記憶體

菜——物件

空盤子等垃圾——未被引用的物件

小妹兒不定時巡迴收垃圾——JVM的一定演算法和執行緒排程回收垃圾

你喊小妹兒收盤子——呼叫System。gc()方法

好了,只能解釋到這兒了

口說無憑,程式碼為證。寫點程式碼驗證一下:

定義一個GCTest類程式碼如下:

Java中有GC就是爽,再也不用自己清理垃圾了

執行結果留給大家去測試了