Java記憶體結構

來源:互聯網
上載者:User

標籤:

一、Java記憶體配置

1. Java有幾種儲存地區?寄存器     --在CPU內部,開發人員不能通過代碼來控制寄存器的分配,有編譯器來管理。堆    --在windows下,棧是向底地址擴充的資料結構,是一塊連續的記憶體的地區,即棧頂的地址和棧的最大容量是系統預先定好的。      --優點:由系統自動分配,速度較快。     --缺點:不夠靈活,程式員無法控制。     --存放基礎資料型別 (Elementary Data Type)、開發過程中就建立的對象(而不是運行過程中)。棧     --是向高地址擴充的資料結構,是不連續的記憶體地區。     --在堆中,沒有堆棧指標,為此也就無法直接從處理器那邊獲得支援。     --堆的好處是有很大的靈活性。如Java編譯器不需要知道從堆裡需要分配多少儲存地區,也不必知道儲存的資料在堆裡會存活多長時間。靜態儲存地區與常量儲存地區     --靜態儲存區用來存放static類型的變數     --常量儲存區用來存放常量類型(final)類型的值,一般在唯讀記憶體中。非RAM儲存     --如流對象,是要發送到另一台機器上。     --持久化的對象,存放在磁碟上。 2. Java記憶體配置     --基礎資料類型直接在棧空間分配。     --方法的形式參數,直接在棧空間分配,當方法調用完成後從棧空間回收。     --引用資料類型,需要用new來建立,既在棧空間分配一個地址空間,又在堆空間指派至的類變數。     --方法的引用參數,在棧空間分配一個地址空間,並指向堆空間的對象區,當方法調用完後從棧空間回收。     --局部變數new出來時,在棧空間和堆空間中分配空間,當局部變數生命週期結束後,棧空間立即被回收,堆空間地區等待GC回收。
     --方法調用時傳入的literal參數,先在棧空間分配,在方法調用完成後從棧空間釋放。     --字串常量在DATA地區分配,this在對空間分配     --數組既在棧空間分配數組名稱,又在堆空間分配數組實際的大小 3. Java記憶體模型     Java虛擬機器將其管轄的記憶體大致分三個邏輯部分:方法區、java棧、java堆。     --方法區是靜態分配的,編譯器將變數綁定在某個儲存位置上,而且這些綁定不會再運行時改變。          常數池,原始碼中的命名常量、string常量和static變數儲存在方法區。     --Java Stack是一個邏輯概念,特點是後進先出。一個棧的空間可能是連續的,也可能是不連續的。          最典型的stack應用是方法的調用,java虛擬機器每調用一次方法就建立一個方法幀(frame),退出時則對應的方法幀被彈出。棧中儲存的資料也是運行時確定的。     --Java堆分配 意味著以隨意的順序,在運行時進行儲存空間分配和收回的記憶體管理模型。          堆中儲存的資料常常是大小、數量和生命期在編譯時間無法確定的。java對象的記憶體總是在heao中分配。   二、Java記憶體回收(GC)1. JVM運行環境中垃圾對象的定義     一個對象建立後被放置在JVM的堆記憶體中,當永遠不再引用這個對象時,它將被JVM在堆記憶體中回收。或當對象在JVMRunspace中無法通過根集合(root set)到達時,這個對象就被稱為垃圾對象。 2. 堆記憶體     在JVM啟動時被建立;堆記憶體中所儲存的對象可以被JVM自動回收,不能通過其他外部手段回收。     堆記憶體可分為兩個地區:新對象區和老對象區     --新對象區可分為三個小區:Eden區、From區、To區 3. JVM中對象的生命週期     建立階段     --為對象分配儲存空間     --開始構造對象     --遞迴調用其超類的構造方法     --進行對象執行個體初始化與變數初始化     --執行構造方法體          應用階段     --特徵:系統至少維護著對象的一個強引用;所有對該對象引用強引用(除非顯示聲明為其他引用)          不可視階段     --如果一個對象已使用完,並且在其可視地區不再使用,應該主動將其設定為null,即obj=null;這樣可以協助JVM及時發現這個垃圾對象,並且可以及時地回收該對象所佔用的系統資源。          4. Java中的析構方法finalize     finalize()方法常稱之為終止器     protected void finalize(){           // finalization code here     }     對象即將被銷毀時,有時需要做一些善後工作,可以把這些操作寫在finalize()方法裡。     Java終止器卻是在對象被銷毀時調用。一旦垃圾收集器準備好釋放無用對象佔用的儲存空間,它首先調用那些對象的finalize()方法,然後才真正回收對象的記憶體。而被丟棄的對象何時被銷毀,應用是無法獲知的。大多數場合,被丟棄對象在應用終止或仍未銷毀。到程式結束的時候,並非所有收尾模組都會得到調用。 5. 應用能干預記憶體回收嗎?     在應用代碼裡控制JVM的記憶體回收運轉是不可能的事。     對記憶體回收有兩個途徑。第一個就是將指向某對象的所有引用變數全部移走。這就相當於向JVM發了一個訊息:這個對象不要了。第二個是調用庫方法System.gc()。第一個是一個告知,而調用System.gc()也僅僅是一個請求。JVM接收這個訊息後,並不是立即做記憶體回收,而只是對幾個記憶體回收演算法做了加權,使記憶體回收操作容易發生,或提早發生,或回收較多而已。     希望JVM及時回收垃圾,是一種需求。其實,還有相反的一種需要:在某段時間內最好不要回收垃圾。要求運行速度最快的即時系統,特別是嵌入式系統,往往希望如此。     Java的記憶體回收機制是為所有java應用進程服務的。因此,任何一個進程都不能命令記憶體回收機製做什麼、怎麼做、做多少。 6. 記憶體回收演算法 *引用計數     該演算法在java虛擬機器沒被使用過,主要是循環參考問題,因為計數並不記錄誰指向他,無法發現這些互動自引用對象。     --怎麼計數?          當引用串連到對象時,對象計數加1          當引用離開範圍或被置為null時減1     --怎麼回收?          遍曆對象列表,計數為0就釋放     --有什麼問題?          循環參考問題  *標記演算法標記演算法的思想是從堆棧和靜態儲存區的對象開始,遍曆所有引用,標記活的對象。對於標記後有兩種處理方式:(1)停止-複製     --所謂停止,就是停止在啟動並執行程式,進行記憶體回收     --所謂複製,就是將活的對象複製到另一個堆上,以使記憶體更緊湊     --優點在於,當大塊記憶體釋放時,有利於整個記憶體的重新分配     --有什麼問題?          ->停止,幹擾程式的正常運行          ->複製,明顯耗費大量時間          ->如果程式比較穩定,垃圾比較少,那麼每次重新複製量是非常大的,非常不合算(2)標記-清除     --也就是將標記為非活的對象釋放,也必須暫停程式運行     --優點就是在程式比較穩定,垃圾比較少的時候,速度比較快     --有什麼問題?          很顯然停止程式運行是一個問題,只清楚也會造成很多記憶體片段     --為什麼這兩個演算法都要暫停程式運行?          如果不暫停,剛才的標記會被啟動並執行程式弄亂             

Java記憶體結構

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.