亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談一下Java中的堆和棧

 更新時(shí)間:2023年04月27日 09:35:25   作者:索碼理  
這篇文章主要介紹了一下Java中的堆和棧,Java數(shù)據(jù)類型在執(zhí)行過程中存儲(chǔ)在兩種不同形式的內(nèi)存中:棧和堆,它們通常由運(yùn)行Java虛擬機(jī)(JVM)的底層平臺(tái)維護(hù),需要的朋友可以參考下

Java數(shù)據(jù)類型在執(zhí)行過程中存儲(chǔ)在兩種不同形式的內(nèi)存中:棧和堆,它們通常由運(yùn)行Java虛擬機(jī)(JVM)的底層平臺(tái)維護(hù)。本文從Java軟件開發(fā)的角度提供了對(duì)這兩種內(nèi)存類型的一些見解。

Java程序是怎么運(yùn)行的

Java程序運(yùn)行在Java Virtual Machine (JVM)中,JVM提供了Java應(yīng)用程序在運(yùn)行時(shí)所需要的任何資源的管理器。這就意味著開發(fā)者寫的應(yīng)用程序或者創(chuàng)建的應(yīng)用程序沒有能力去直接獲取系統(tǒng)資源(不管是硬件還是軟件),除非JVM能提供給這些資源。所以在Java中,程序運(yùn)行順序如下圖:

JVM層使得Java平臺(tái)能夠獨(dú)立運(yùn)行,其他編程語(yǔ)言,例如C/C++沒有使用類似JVM層的東西,因此它們不是跨平臺(tái)的語(yǔ)言,即使它們是可移植的語(yǔ)言。它們就像下圖一樣:

這兩種形式有優(yōu)點(diǎn)也有缺點(diǎn),Java已經(jīng)有了自己的生態(tài)系統(tǒng)。與此同時(shí),像C/C++這樣的編程語(yǔ)言能夠直接訪問系統(tǒng)資源,從而更有利于優(yōu)化核心單元的使用,從而產(chǎn)生超級(jí)快速和高效的程序。但兩者在軟件開發(fā)領(lǐng)域都有各自的用途。

所有編程語(yǔ)言在編譯和執(zhí)行過程中都有許多相似之處。其中最重要的一點(diǎn)就是內(nèi)存管理,無(wú)論使用哪種語(yǔ)言,內(nèi)存管理對(duì)程序的整體效率都有重要影響,因?yàn)楣芾砗脙?nèi)存資源,從而才能管理好應(yīng)用程序性能。

Java中的運(yùn)行內(nèi)存

應(yīng)用程序之間的一個(gè)常見現(xiàn)象是,每個(gè)應(yīng)用程序都需要一些內(nèi)存才能以最佳方式工作,該內(nèi)存由底層平臺(tái)提供。在Java中,JVM提供了這些內(nèi)存資源(當(dāng)然需要操作系統(tǒng)授權(quán))。Java中,JVM內(nèi)存主要分為5個(gè)部分分別為:方法區(qū)、堆、棧、PC寄存器和本地方法區(qū)。

本文主要關(guān)注堆和棧。內(nèi)存不像一張白紙,程序員只需要草草記下就可以存儲(chǔ)數(shù)據(jù),在使用內(nèi)存之前,需要對(duì)其進(jìn)行結(jié)構(gòu)化。棧和堆是使用內(nèi)存時(shí)遵循的數(shù)據(jù)結(jié)構(gòu),在程序執(zhí)行期間,存儲(chǔ)的數(shù)據(jù)用于各種目的,這取決于程序的目的是什么。

JVM決定程序執(zhí)行期間使用的運(yùn)行時(shí)數(shù)據(jù)區(qū)域。有些數(shù)據(jù)區(qū)域是依賴于JVM的,這意味著它們是在JVM啟動(dòng)時(shí)創(chuàng)建的,并在JVM的整個(gè)生命周期中持續(xù)存在。但是,每個(gè)線程都創(chuàng)建和銷毀其他數(shù)據(jù)區(qū)域。JVM可以同時(shí)執(zhí)行多個(gè)執(zhí)行線程,這意味著每個(gè)線程都有自己的pc(Program Counter,程序計(jì)數(shù)器)來維護(hù)正在執(zhí)行的當(dāng)前指令的位置,還有一個(gè)棧幀來保存靜態(tài)內(nèi)存分配。

棧是內(nèi)存中的一種結(jié)構(gòu),開發(fā)人員在其中存儲(chǔ)元素,其方式允許只從棧頂檢索數(shù)據(jù)——通常稱為先入后出(FILO或LIFO)。因?yàn)槊總€(gè)線程都維護(hù)一個(gè)私有的JVM棧,它被用來存儲(chǔ)與它們的靜態(tài)內(nèi)存分配相關(guān)的變量。特定于我們?cè)诖a中聲明和使用的方法的原語(yǔ)變量實(shí)際上存儲(chǔ)在棧區(qū)域中。另外,對(duì)實(shí)際存儲(chǔ)在堆內(nèi)存中的對(duì)象的引用也存儲(chǔ)在堆棧區(qū)域中。因此,任何本地分配的內(nèi)存都存儲(chǔ)在堆棧中。

堆棧內(nèi)存的默認(rèn)大小可以使用JVM參數(shù)-Xss來更改。有時(shí),如果分配了太多變量或方法遞歸調(diào)用自身,則堆??赡芤绯?。所有Java程序員都知道的一個(gè)常見錯(cuò)誤是Java.lang.stackoverflowerror,當(dāng)棧內(nèi)存不足時(shí)提示該錯(cuò)誤。Java中的每個(gè)方法調(diào)用都會(huì)在棧中分配一塊內(nèi)存,因此,設(shè)計(jì)糟糕的遞歸方法調(diào)用很容易占用所有棧內(nèi)存,導(dǎo)致棧內(nèi)存溢出錯(cuò)誤。

堆是JVM一啟動(dòng)就創(chuàng)建的內(nèi)存區(qū)域,它會(huì)一直存在,直到JVM被銷毀。與棧不同的是,棧是單個(gè)線程的屬性(因?yàn)槊總€(gè)線程都有自己的棧),堆實(shí)際上是由JVM本身管理的全局內(nèi)存,此內(nèi)存在運(yùn)行時(shí)用于為對(duì)象分配內(nèi)存。因此,對(duì)象的實(shí)例化可以是用戶定義的類、JDK或其他庫(kù)類。簡(jiǎn)而言之,使用new關(guān)鍵字創(chuàng)建的任何對(duì)象都存儲(chǔ)在堆內(nèi)存中。堆內(nèi)存中的對(duì)象可被JVM運(yùn)行的所有線程訪問。訪問管理非常復(fù)雜,使用了非常復(fù)雜的算法,這就是JVM垃圾收集器發(fā)揮作用的地方。

堆的默認(rèn)大小可以使用JVM參數(shù)-Xms-Xmx來更改。隨著對(duì)象的創(chuàng)建和銷毀,堆的大小也會(huì)增加或減少,如果達(dá)到最大內(nèi)存限制后并嘗試進(jìn)一步分配內(nèi)存,則拋出java.lang.OutOfMemoryError。

堆中的字符串池(StringPool)

Java.lang.String類是Java中使用最多的類,因此,應(yīng)該特別注意它的效率問題。與基本數(shù)據(jù)類型相比,字符串的操作效率總是很慢,所以,必須采用某種方式使得字符串對(duì)象操作的效率和便利性方面類似或者接近于基本數(shù)據(jù)類型,為了達(dá)到這個(gè)目的就在堆中分配了一塊特殊內(nèi)存區(qū)域(StringPool),創(chuàng)建的任何字符串對(duì)象都由JVM存儲(chǔ)在StringPool中。與堆中創(chuàng)建的其他對(duì)象相比,這提高了性能。

從代碼示例說明堆和棧

為了更好地說明在Java中堆和棧內(nèi)存的使用,讓我們寫一個(gè)簡(jiǎn)單的程序,并決定哪個(gè)分配分配到哪個(gè)內(nèi)存——堆或棧:

public class HeapAndStackTest {
    public static void main(String[] args) {
        int x=10;
        int y=20;
        String greet = "Hello";
        Date d = new Date();
        diff(x, y);
    }

    public static int diff(int x1, int x2) {
        return x2-x1;
    }
}

這段代碼運(yùn)行方式如下:

  • 程序啟動(dòng),JVM將Java運(yùn)行時(shí)環(huán)境(JRE)類加載到堆中。
  • 在遇到main() 方法時(shí),會(huì)創(chuàng)建一個(gè)棧幀。
  • 局部變量xy存儲(chǔ)在棧中。
  • 字符串greet分配在堆的StringPool區(qū)域中。
  • Date對(duì)象分配在堆區(qū),而它的引用d存儲(chǔ)在棧中。

Img

總結(jié)

棧和堆是Java程序在代碼執(zhí)行期間使用的兩個(gè)區(qū)域。除了這兩個(gè)之外,還有其他內(nèi)存區(qū)域,如方法區(qū)域、寄存器、本地方法域等等。每種區(qū)域在Java應(yīng)用程序中都有其特定的用途。但是,從程序員的角度來看,棧和堆是JVM必須理解的區(qū)域。

到此這篇關(guān)于淺談一下Java中的堆和棧的文章就介紹到這了,更多相關(guān)Java的堆和棧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java發(fā)送form-data請(qǐng)求實(shí)現(xiàn)文件上傳的示例代碼

    java發(fā)送form-data請(qǐng)求實(shí)現(xiàn)文件上傳的示例代碼

    最近做一個(gè)需求,需要請(qǐng)求第三方接口上傳文件,該請(qǐng)求類型是form-data請(qǐng)求,本文就來介紹一下java發(fā)送form-data請(qǐng)求實(shí)現(xiàn)文件上傳的示例代碼,感興趣的可以了解一下
    2023-12-12
  • Java AQS中ReentrantReadWriteLock讀寫鎖的使用

    Java AQS中ReentrantReadWriteLock讀寫鎖的使用

    ReentrantReadWriteLock稱為讀寫鎖,它提供一個(gè)讀鎖,支持多個(gè)線程共享同一把鎖。這篇文章主要講解一下ReentrantReadWriteLock的使用和應(yīng)用場(chǎng)景,感興趣的可以了解一下
    2023-02-02
  • 聊一聊jdk1.8中的ArrayList 底層數(shù)組是如何擴(kuò)容的

    聊一聊jdk1.8中的ArrayList 底層數(shù)組是如何擴(kuò)容的

    這篇文章主要介紹了聊一聊jdk1.8中的ArrayList 底層數(shù)組是如何擴(kuò)容的,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • C++排序算法之桶排序原理及實(shí)現(xiàn)詳解

    C++排序算法之桶排序原理及實(shí)現(xiàn)詳解

    這篇文章主要介紹了C++排序算法之桶排序原理及實(shí)現(xiàn)詳解, C++ 桶排序是一種線性時(shí)間復(fù)雜度的排序算法,它通過將待排序元素分配到不同的桶中,然后對(duì)每個(gè)桶中的元素進(jìn)行排序,最后將所有桶中的元素按順序合并得到有序序列,需要的朋友可以參考下
    2023-10-10
  • 淺談一下Java中的幾種JVM級(jí)別的鎖

    淺談一下Java中的幾種JVM級(jí)別的鎖

    這篇文章主要介紹了淺談一下Java中的幾種JVM級(jí)別的鎖,當(dāng)存在安全漏洞時(shí),也必須有相應(yīng)的防護(hù)措施。順應(yīng)這種趨勢(shì),虛擬"鎖"被發(fā)明出來,以解決線程的安全問題。在這篇文章中,我們將研究多年來出現(xiàn)的?Java?中幾種典型的?JVM?級(jí)鎖,需要的朋友可以參考下
    2023-08-08
  • Java使用MyBatis框架分頁(yè)的5種方式

    Java使用MyBatis框架分頁(yè)的5種方式

    這篇文章主要為大家詳細(xì)介紹了Java使用MyBatis框架分頁(yè)的5種方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • SpringCloud中的Stream服務(wù)間消息傳遞詳解

    SpringCloud中的Stream服務(wù)間消息傳遞詳解

    這篇文章主要介紹了SpringCloud中的Stream服務(wù)間消息傳遞詳解,Stream 就是在消息隊(duì)列的基礎(chǔ)上,對(duì)其進(jìn)行封裝,可以是我們更方便的去使用,Stream應(yīng)用由第三方的中間件組成,應(yīng)用間的通信通過輸入通道和輸出通道完成,需要的朋友可以參考下
    2024-01-01
  • Java加載ICC文件的方法和示例代碼

    Java加載ICC文件的方法和示例代碼

    ICC文件,通常用于顏色管理,定義了如何將一個(gè)顏色空間轉(zhuǎn)換為另一個(gè)顏色空間,在Java中,我們可能需要加載這些文件來進(jìn)行顏色轉(zhuǎn)換或管理,本文將為您提供加載ICC文件的方法和示例代碼,需要的朋友參考下吧
    2023-08-08
  • SpringBoot解析指定Yaml配置文件的實(shí)現(xiàn)過程

    SpringBoot解析指定Yaml配置文件的實(shí)現(xiàn)過程

    這篇文章主要介紹了SpringBoot解析指定Yaml配置文件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • 詳解Spring中Lookup注解的使用

    詳解Spring中Lookup注解的使用

    我們知道在spring容器中單獨(dú)的一個(gè)抽象類是不能成為一個(gè)bean的,那么有沒有辦法呢?這個(gè)時(shí)候我們可以使用Lookup注解,下面跟隨小編看下Spring中Lookup注解的使用
    2021-10-10

最新評(píng)論