1. 程式人生 > >Java 中的 JVM、堆和棧 -- 初步了解

Java 中的 JVM、堆和棧 -- 初步了解

eap 調用 程序 mmm 劃分 創建 都是 分配 2015a

JVM -- Java Virtual Machine(Java虛擬機)

  —— 因為要說堆和棧,所以我們必須要先簡單的說一下JVM。(JVM詳細請找度娘啦~)

  首先,我們都知道 java 一直宣傳的口號是:一次編譯,到處運行。其實它具體的實現是因為 java 程序經過一次編譯之後,將 java 代碼編譯為字節碼也就是 class 文件,然後只要在不同平臺上安裝對應的JVM,就可以運行字節碼文件,運行我們編寫的Java程序。

  所以說它是 java 的核心和基礎。

  個人覺得,它大概的執行過程就是:

    ① 加載 .class 文件(它也只能加載class文件)

    ② 管理並分配內存

    ③ 執行垃圾回收

  (emmm..就到這吧。下面才是重點)

  JVM 的內存分配 -- JVM 的內存劃分為五片,分別是:PC寄存器、方法區、堆、Java棧、本地方法棧

    1. 方法區和堆由所有線程共享

    2. Java棧和PC寄存器由線程獨享,在新線程的創建的時間裏

    3. 本地方法棧:存儲本地方法調用的狀態

  下面重點說一下,堆和棧。

堆(Heap)和棧(Stack)

  一個簡單總結:

    棧(stack):空間小,速度比較快, 用來放對象的引用,存取速度比堆要快。

    堆(heep): 大,一般所有創建的對象都放在這裏。

  

  堆和棧是兩種內存分配的兩個統稱,都是Java用來在Ram中存放數據的地方(java 自動管理棧和堆,程序員不能直接設置)。可能有很多種不同的實現方式,但是實現要符合幾個基本的概念:

  1. 棧--後進先出。對棧而言,棧中的新加數據項放在其他數據的頂部,移除時你也只能移除最頂部的數據(不能越位獲取)。

  2. 對堆而言,數據項位置沒有固定的順序。你可以以任何順序插入和刪除,因為他們沒有“頂部”數據這一概念。

  棧(Stack):棧內存首先是一片內存區域,存儲的都是些局部變量(凡是定義在方法中的都是局部變量,方法外的是全局變量)

  註意:for 循環內部定義的也是局部變量,是先加載函數才能進行局部變量的定義,所以方法先進棧,然後再定義變量。

  變量有自己的作用域(也就是由{...}括起來的區域),一旦離開作用域,變量就會被釋放(大概是方法執行完成到方法外面的時候,變量銷毀的意思)。棧內存更新速度很快,因為局部變量的生命周期都很短。

  棧有一個很重要的特殊性,就是存在棧中的數據可以共享。例:

    我們同時定義:

            int a = 3; 
int b = 3;
    編譯器先處理int a = 3;首先它會在棧中創建一個變量為a 的引用,然後查找有沒有字面值為 3 的地址,沒找到,就開辟一個存放 3 這個字面值的地址,然後將 a 指向 3 的地址。接著處理int b = 3;在創建完 b 的引用變量後,由於在棧中已經有 3 這個字面值,便將 b 直接指向 3 的地址。
這樣,就出現了 a 與 b 同時均指向 3 的情況。特別註意的是,這種字面值的引用與類對象的引用不同。
 

  堆(Heap):存儲的是數組和對象(其實數組就是對象),凡是 new 建立的都是在堆中,堆中存放的都是實體,實體用於封裝數據,而且是封裝多個(實體的多個屬性),如果一個數據消失,這個實體也沒有消失,還可以用,所以堆是不會隨時釋放的,但是棧不一樣,棧裏面存放的都是單個變量,變量被釋放了,那就沒有了。堆裏面的實體雖然不會被釋放,但是會被當成垃圾(java的垃圾回收機制會不定時的收取)。

  堆和棧的聯系:

   假設我們現在在主函數裏面聲明一個數組 int arr = new int[3] ,它現在是沒有值的,只是有這麽一個數組對象創建在堆裏面,然後它有了一個內存地址,並且進行了默認的初始化(未初始化的數據是不能用的,所以在棧裏面不能用,堆裏面能用,就是因為默認初始化過了)。

   然後棧裏面存放的只是堆內存地址(對象的引用),而不是這個 arr 數組的這個實體。我們通過棧裏面的這個地址指向 arr 數組這個實體,進行操作。

   當 arr 被置為 null ,也就是沒有任何指向引用。arr 這時候當做一個垃圾,不定時的時間內自動回收(java 自動回收機制)。

  堆與棧的區別:

    1.棧內存存儲的是局部變量而堆內存存儲的是實體;

    2.棧內存的更新速度要快於堆內存,因為局部變量的生命周期很短;

    3.棧內存存放的變量生命周期一旦結束就會被釋放,而堆內存存放的實體會被垃圾回收機制不定時的回收。

    4.棧是後進先出的,拿的是頂部的數據。而堆沒有頂部的概念。

Java 中的 JVM、堆和棧 -- 初步了解