1. 程式人生 > >Java程式為什麼無須delete語句進行記憶體回收?

Java程式為什麼無須delete語句進行記憶體回收?

 垃圾回收機制Java相對於C++的一種巨大改進,它避免了因為程式設計師忘記釋放記憶體而造成記憶體溢位的錯誤。所以在Java程式中,根本不需要使用delete語句,JVM會自動的去檢查哪些記憶體應該回收了,在後臺就自動回收了,為程式設計師省了不少的事情。

   大家知道,Java除了那8種基本型別以外,其他都是物件型別(又稱為引用型別)的資料。JVM會把程式建立的物件存放在堆空間中,那什麼是堆空間呢?其實,堆(Heap)是一個執行時的資料儲存區,從它可以分配大小各異的空間。一般,執行時的資料儲存區有堆(Heap)和堆疊(Stack),所以要先看它們裡面可以分配哪些型別的物件實體,然後才知道如何均衡使用這倆種儲存區。一般來說,桟中存放的是非

static的自動變數,函式引數,表示式的臨時結果和函式返回值(如果他們沒有被放到暫存器中)。桟中的這些實體資料的分配和釋放均是由系統自動完成的,堆中存放的實體資料都是程式中顯式分配的,沒有自動垃圾回收機制的系統中必須由程式程式碼顯示的釋放這些實體。

     堆的管理,不同的語言實現是不同的。如c語言就沒有把堆的分配和釋放做到語言的層次,它對堆空間物件的操作是通過其庫函式malloc()和free()來實現的;而C++直接把堆堆空間的物件的分配和釋放做到語言層次了。使用newdelete語句,Java就做的更徹底了,應用開發者只需要用堆分配的時候建立就行了,何時釋放如何釋放,都有Java虛擬機器(

JVM)來做,而不需要程式程式碼來顯式的釋放。

   說明:Java虛擬機器規範並沒有強制規定要實現自動回收垃圾功能功能,但目前大多數JVM都實現了自動垃圾回收機制,只是它們各自的實現的演算法不同。

    JVM有著各種版本的實現,它們基本上都會有垃圾回收的機制,也就是堆記憶體的管理的自動進行。那麼,又該如何讓知道物件已經被回收了呢?Java中父類java.lang.Object中有個finalize方法,它會在垃圾回收器認為這個物件時垃圾了之後,真正回收之前被呼叫。因為所有的類都繼承自Object,所以它們都會有finalize方法,程式設計師可以在這個方法中需要寫一些需要在物件被回收前做的事情,例如關閉資料庫連線

finalize方法原型如下:

protected void finalize() throws Throwable

一般在呼叫這個方法執行啊,垃圾回收器能檢測出不在被引用的物件,如果這些物件覆蓋了finalize方法,就要呼叫該方法。

    另外,在java.lang.System類中,有一個gc方法,它對JVM的垃圾回收也有一些影響,通過i型按時的呼叫它可以請求開始垃圾回收器執行緒,開始垃圾回收,但是垃圾回收執行緒是否立即開始還是由JVM的演算法決定的。java.lang.Runtime類的gc方法與System的作用一樣,只不過Runtime是一個單例模式的類,需要用getRuntime方法來獲得它的例項,然後才能呼叫gc方法,程式碼如下所示:

System.gc();

Runtime.getRuntime().gc();

  注意:垃圾回收執行緒是一個優先順序很低的執行緒。

可以這樣回答:

Java的堆記憶體資料的釋放功能是由垃圾回收器自動進行的,無需程式設計師顯式的呼叫delete方法。該機制有效的避免了因為程式設計師忘記釋放記憶體而造成記憶體溢位的錯誤,相對於C++等需要顯示釋放記憶體的語言,是一中巨大的改進。