国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

復(fù)習(xí)一下JVM內(nèi)存結(jié)構(gòu)

這篇具有很好參考價(jià)值的文章主要介紹了復(fù)習(xí)一下JVM內(nèi)存結(jié)構(gòu)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、程序計(jì)數(shù)器

程序計(jì)數(shù)器內(nèi)存很小,可以看作是當(dāng)前線程所執(zhí)行字節(jié)碼的行號(hào)指示器。

有了它,程序就能被正確的執(zhí)行。

因?yàn)橛?strong>線程切換的存在,則每個(gè)線程必須有各自獨(dú)立的程序計(jì)數(shù)器,即線程私有的內(nèi)存。

這里再解釋一下什么是線程切換,線程切換指的是:

單處理器在執(zhí)行多線程時(shí)所進(jìn)行的線程切換,多線程的交替運(yùn)行會(huì)產(chǎn)生同時(shí)運(yùn)行的錯(cuò)覺。

程序計(jì)數(shù)器不會(huì)發(fā)生OOM原因:

占用內(nèi)存非常小,當(dāng)線程結(jié)束時(shí)程序計(jì)數(shù)器也會(huì)隨之回收。

二、本地方法棧與虛擬機(jī)棧

棧是stack的翻譯,那stack又是什么?

在英文語境中,stack指的是一摞盤子堆疊起來、一摞書堆疊起來的這種狀態(tài),也就是 a stack of books. 借這種現(xiàn)實(shí)物理情境來描述計(jì)算機(jī)中的數(shù)據(jù)結(jié)構(gòu)。

這種結(jié)構(gòu)的特征就是LIFO, Last In First Out, 即后進(jìn)先出。

也就是,一摞盤子,你只能一個(gè)一個(gè)往上堆,也只能一個(gè)一個(gè)從頂上往外取,對(duì)應(yīng)**入棧和出棧(彈棧)**的操作。

以上是對(duì)棧這種結(jié)構(gòu)的解釋。

接下來說這兩種棧結(jié)構(gòu):Native Method Stack 和 JVM stack.

棧是線程私有的,它的生命周期和線程是相同的。

棧里面保存棧幀。

什么是棧幀?

每個(gè)方法執(zhí)行時(shí)都會(huì)創(chuàng)建一個(gè)棧幀。棧幀存儲(chǔ)了局部變量表、操作數(shù)棧、動(dòng)態(tài)連接和方法出口等信息。每個(gè)方法從調(diào)用到運(yùn)行結(jié)束的過程,就對(duì)應(yīng)著一個(gè)棧幀在棧中入棧到出棧的過程

棧有可能出現(xiàn)什么異常?

StackOverflowErrorOutOfMemoryError

前者主要是深度遞歸和復(fù)雜嵌套方法調(diào)用造成。

后者的話發(fā)生在棧在進(jìn)行動(dòng)態(tài)擴(kuò)展的時(shí)候,也就是說 jvm 實(shí)現(xiàn)中棧的大小此時(shí)是不固定的,因?yàn)?strong>線程操作需要更多的??臻g而在申請(qǐng)內(nèi)存的時(shí)候失敗就會(huì)拋出OutOfMemoryError錯(cuò)誤。

JVM 中的棧包括 Java 虛擬機(jī)棧和本地方法棧。

兩者的區(qū)別就是:

Java 虛擬機(jī)棧為 JVM 執(zhí)行 Java 方法服務(wù),本地方法棧則為 JVM 使用到的 Native 方法(比如C或C++)服務(wù)。

四、堆

Heap有什么特征?

  • ??JVM管理的最大內(nèi)存區(qū)域

  • ??線程共享

  • ??存放對(duì)象實(shí)例

  • ??內(nèi)存空間可以物理上不連續(xù)

  • ??垃圾回收的主要區(qū)域

關(guān)于垃圾回收的內(nèi)容這里不展開講了。

五、方法區(qū)

JVM規(guī)范把方法區(qū)描述為堆的一個(gè)邏輯部分,但有一個(gè)別名叫Non-Heap,即Heap中的Non-heap, 也是說明它和堆其實(shí)還是不一樣的。

方法區(qū)有什么特征?

??線程共享

??存放已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)

??垃圾回收較少出現(xiàn),甚至可選擇不進(jìn)行垃圾回收

方法區(qū)的垃圾回收主要針對(duì)常量池的回收和對(duì)類的卸載。

這里主要說一下運(yùn)行時(shí)常量池:

Class文件中除了有類的版本、字段、方法、接口等描述信息外還有一項(xiàng)常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符號(hào)引用,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放。

這里出現(xiàn)了兩個(gè)常量池,它們是不一樣的,一個(gè)叫常量池,一個(gè)叫運(yùn)行時(shí)常量池(Runtime Constant Pool), 運(yùn)行時(shí)常量池具備動(dòng)態(tài)性,那怎么理解動(dòng)態(tài)性呢?

就是說除了編譯期產(chǎn)生的常量進(jìn)入了常量池在類加載后又緊接著進(jìn)入了運(yùn)行時(shí)常量池以外,運(yùn)行期間新的常量也會(huì)進(jìn)入運(yùn)行時(shí)常量池。

關(guān)于類加載的介紹我們?cè)賳为?dú)寫一篇。

《學(xué)一點(diǎn)關(guān)于JVM類加載的知識(shí)》

下面舉一些例子把這里具體搞搞清楚。

常量池有什么用 ?

**優(yōu)點(diǎn):**常量池避免了頻繁的創(chuàng)建和銷毀對(duì)象而影響系統(tǒng)性能,其實(shí)現(xiàn)了對(duì)象的共享。

下面具體講一下字符串常量池(String常量池):

String 是由 final 修飾的類,是不可以被繼承的。通常有兩種方式來創(chuàng)建對(duì)象。

//1、這種存在Heap中,每次new都會(huì)創(chuàng)建一個(gè)全新對(duì)象
String?str?=?new?String("abcd");
?
//2、這種是在棧上創(chuàng)建對(duì)象引用變量str,指向字符串常量池中的“abcd”(沒有的話新建一個(gè))
String?str?=?"abcd";

關(guān)于字符串 + 號(hào)連接問題:

對(duì)于字符串常量的 + 號(hào)連接,在程序編譯期,JVM就會(huì)將其優(yōu)化為 + 號(hào)連接后的值。所以在編譯期其字符串常量的值就確定了。

String?a?=?"a1";???
String?b?=?"a"?+?1;???
System.out.println((a?==?b));?//result?=?true??
?
String?a?=?"atrue";???
String?b?=?"a"?+?"true";???
System.out.println((a?==?b));?//result?=?true?
?
String?a?=?"a3.4";???
String?b?=?"a"?+?3.4;???
System.out.println((a?==?b));?//result?=?true?

關(guān)于字符串引用 + 號(hào)連接問題:

對(duì)于字符串引用的 + 號(hào)連接問題,由于字符串引用在編譯期是無法確定下來的,在程序的運(yùn)行期動(dòng)態(tài)分配并創(chuàng)建新的地址存儲(chǔ)對(duì)象。

    public?static?void?main(String[]?args){
    ???????String?str1?=?"a";
    ???????String?str2?=?"ab";
    ???????String?str3?=?str1?+?"b";
    ???????System.out.print(str2?==?str3);//false
    ????}

通過 jad 反編譯工具,分析上述代碼到底做了什么。

    public?class?TestDemo{
    ????public?TestDemo(){
    ????}
    ????public?static?void?main(String?args[]){
    ????????String?s?=?"a";
    ????????String?s1?=?"ab";
    ????????String?s2?=?(new?StringBuilder()).append(s).append("b").toString();
    ????????System.out.print(s1?=?s2);
    ????}
    }

發(fā)現(xiàn)?new 了一個(gè) StringBuilder 對(duì)象,然后使用 append 方法優(yōu)化了 + 操作符。new 在上創(chuàng)建對(duì)象,而 String s1=“ab”則是在常量池中創(chuàng)建對(duì)象,兩個(gè)應(yīng)用所指向的內(nèi)存地址是不同的,所以 s1 == s2 結(jié)果為 false。

這里引出一個(gè)實(shí)際開發(fā)中關(guān)于字符串拼接的問題。就是盡量不要在 for 循環(huán)中使用 + 號(hào)來操作字符串。

因?yàn)槿绻谩?”號(hào)的話,每次循環(huán)都會(huì)創(chuàng)建和銷毀一個(gè)StringBuilder對(duì)象,這樣還不如在循環(huán)外創(chuàng)建一個(gè)StringBuilder對(duì)象,然后使用append方法。

    public?static?void?main(String[]?args){
    ????????StringBuilder?s?=?new?StringBuilder();
    ????????for(int?i?=?0;?i?<?100;?i++){
    ????????????s.append("a");
    ????????}
    ????}

使用final修飾的字符串

    public?static?void?main(String[]?args){
    ????????final?String?str1?=?"a";
    ????????String?str2?=?"ab";
    ????????String?str3?=?str1?+?"b";
    ????????System.out.print(str2?==?str3);//true
    ????}

final 修飾的變量是一個(gè)常量,編譯期就能確定其值。所以 str1 + "b"就等同于 "a" + "b",所以結(jié)果是 true。

String對(duì)象的intern方法。

    public?static?void?main(String[]?args){
    ????????String?s?=?"ab";
    ????????String?s1?=?"a";
    ????????String?s2?=?"b";
    ????????String?s3?=?s1?+?s2;
    ????????System.out.println(s3?==?s);//false
    ????????System.out.println(s3.intern()?==?s);//true
    ????}

通過前面學(xué)習(xí)我們知道,s1+s2 實(shí)際上在堆上 new 了一個(gè) StringBuilder 對(duì)象,而 s 在常量池中創(chuàng)建對(duì)象 “ab”,所以 s3 == s 為 false。

但是 s3 調(diào)用 intern 方法,返回的是s3的內(nèi)容(ab)在常量池中的地址值。所以 s3.intern() == s 結(jié)果為 true。


往期推薦:

●?師爺,翻譯翻譯什么叫AOP

● 終于搞懂動(dòng)態(tài)代理了!

●?學(xué)會(huì)@ConfigurationProperties月薪過三千

●?0.o?讓我看看怎么個(gè)事兒之SpringBoot自動(dòng)配置

●?不是銀趴~是@Import!

●?Java反射,看完就會(huì)用文章來源地址http://www.zghlxwxcb.cn/news/detail-829300.html

到了這里,關(guān)于復(fù)習(xí)一下JVM內(nèi)存結(jié)構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包