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

Java?對(duì)象在?JVM?中的內(nèi)存布局超詳細(xì)解說

 更新時(shí)間:2022年09月05日 17:06:17   作者:new?Handsome()  
這篇文章主要介紹了Java?對(duì)象在?JVM?中的內(nèi)存布局超詳細(xì)解說,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

一、new 對(duì)象的幾種說法

初學(xué) Java 面向?qū)ο蟮臅r(shí)候,實(shí)例化對(duì)象的說法有很多種,我老是被這些說法給弄暈。

public class Test {
    public static void main(String[] args) {
        // 創(chuàng)建一個(gè) ProgramLanguage 對(duì)象, 對(duì)象名是 java
        ProgramLanguage java = new ProgramLanguage();
        // 實(shí)例化一個(gè) ProgramLanguage 對(duì)象, 對(duì)象名是 c
        ProgramLanguage c = new ProgramLanguage();
        // 把 ProgramLanguage 類實(shí)例化, 實(shí)例化后的對(duì)象的對(duì)象名是 python
        ProgramLanguage python = new ProgramLanguage();
    }
}

class ProgramLanguage {
    private Integer id;
    private String name;
}

下面的三種說法的操作都是實(shí)例化對(duì)象,只是說法不一樣而已

  • 創(chuàng)建一個(gè) xxx 對(duì)象
  • 實(shí)例化一個(gè) xxx 對(duì)象
  • ③ 把 xxx 類實(shí)例化

二、Java 對(duì)象在內(nèi)存中的存在形式

這里先簡(jiǎn)單看一看 Java 對(duì)象在內(nèi)存中的存在形式和幾個(gè)內(nèi)存相關(guān)的概念,后面還會(huì)詳細(xì)介紹的。先看下面的幾個(gè)知識(shí)點(diǎn):

1. 棧幀(Frame)

  • ① 方法被調(diào)用則棧幀創(chuàng)建,方法執(zhí)行結(jié)束則棧幀銷毀
  • ② 棧幀中存儲(chǔ)了方法的局部變量信息
  • ③ 棧幀是分配給方法的一段??臻g

  • main 方法作為程序的入口肯定是第一個(gè)被調(diào)用的方法,所以會(huì)先創(chuàng)建 main 方法的棧幀
  • 在 main 方法中調(diào)用了 test1 方法,并傳入【55】作為參數(shù)給 test1 方法的局部變量 v,所以第二個(gè)創(chuàng)建的是 test1 方法的棧幀
  • test1 方法中的代碼很快就執(zhí)行完了,所以 test1 的棧幀很快會(huì)被銷毀(方法執(zhí)行結(jié)束后該方法的棧幀銷毀)
  • 在 main 方法中調(diào)用了 test2 方法,并傳入【88】作為參數(shù)給 test2 方法的局部變量 v,所以第三個(gè)創(chuàng)建的是 test2 方法的棧幀
  • 在 test2 方法中調(diào)用了 test3 方法,并傳入【666】作為參數(shù)給 test3 方法的局部變量 v,所以第四個(gè)創(chuàng)建的是 test3 方法的棧幀
  • 當(dāng) test3 方法執(zhí)行完畢后,test3 方法的棧幀被銷毀
  • test3 方法的結(jié)束也正是 test2 方法的結(jié)束,所以 test2 方法的棧幀也被銷毀
  • test2 方法的結(jié)束表示 main 方法的結(jié)束,所以 main 方法的棧幀會(huì)被銷毀

2. 對(duì)象在內(nèi)存中的存在形式 ①

  • Java 中的所有對(duì)象都是通過 new 關(guān)鍵字創(chuàng)建出來的(new 關(guān)鍵字:實(shí)例化一個(gè)對(duì)象;向空間申請(qǐng)一段內(nèi)存,用于存放剛剛實(shí)例化的對(duì)象)
  • 所有的對(duì)象都存儲(chǔ)在空間
  • 所有保存對(duì)象的變量都是引用類型
  • 局部變量是放在空間
  • Java 運(yùn)行時(shí)環(huán)境中有個(gè)垃圾回收器(garbage collector),會(huì)自動(dòng)回收沒有被使用的(堆空間的)內(nèi)存
  • 當(dāng)一個(gè)對(duì)象沒有被任何引用指向的時(shí)候,會(huì)被 GC 回收掉內(nèi)存

分析下面的代碼的內(nèi)存布局:

public class DogDemo {
    public static void main(String[] args) {
        Dog doggy = new Dog();
        doggy.age = 6;
        doggy.weight = 3.14;
    }
}

  • main 方法被調(diào)用,會(huì)在棧空間創(chuàng)建 main 方法的棧幀,main 方法的棧幀中會(huì)存放 main 方法中的局部變量信息(包括 args 和 main 方法中對(duì)象的引用 doggy
  • 在 main 方法中,通過 new 關(guān)鍵字實(shí)例化了 Dog 對(duì)象,Dog 對(duì)象存儲(chǔ)在空間
  • 堆空間中有一段內(nèi)存用于存儲(chǔ)類的對(duì)象的數(shù)據(jù),這段內(nèi)存中存放了 Dog 對(duì)象的屬性信息(如 age、weight)
  • ??臻g中的 doggy 變量代表堆空間中的對(duì)象的地址(通過地址可以訪問對(duì)象)

分析下面的代碼的內(nèi)存布局(稍微復(fù)雜)

public class Dog {
    public int price;
}
public class Person {
    public int age;
    public Dog dog;
}
public class Test {
    public static void main(String[] args) {
        Dog doggy = new Dog();
        doggy.price = 255;

        Person yeTing = new Person();
        yeTing.age = 20;
        yeTing.dog = doggy;
    }
}

  • main 方法被調(diào)用,會(huì)在??臻g創(chuàng)建 main 方法的棧幀,main 方法的棧幀中會(huì)存放 main 方法中的局部變量信息(包括 args、main 方法中對(duì)象的引用 doggy、對(duì)象的引用 yeTing)
  • 在 main 方法中,通過 new 關(guān)鍵字實(shí)例化了 Dog 對(duì)象,Dog 對(duì)象存儲(chǔ)在空間。堆空間中有一段內(nèi)存用于存儲(chǔ) Dog 對(duì)象的屬性信息(如 price = 255)
  • 在 main 方法中,通過 new 關(guān)鍵字實(shí)例化了 Person 對(duì)象,Person 對(duì)象存儲(chǔ)在空間。堆空間中有一段內(nèi)存用于存儲(chǔ) Person 對(duì)象的屬性信息(如 age = 20),堆空間中,Person 對(duì)象的屬性 dog 是 Dog 對(duì)象的引用,所以它指向的是堆空間中的 Dog 對(duì)象(dog 指向的是??臻g中的 doggy 引用的堆空間的 Dog 對(duì)象。doggy 和 yeTing 指向的 Person 對(duì)象中的 dog 屬性指向的是同一個(gè)對(duì)象)
  • 引用變量不一定是在??臻g(也可能是在堆空間,如上圖中 yeTing 指向的 Person 對(duì)象中 dog,這個(gè) dog 就是引用變量。但是,它是在堆空間。)
  • 引用變量指向?qū)ο髮?shí)際上保存的是對(duì)象在堆空間中的地址值(如:doggy 保存的是 Dog 對(duì)象在堆空間的地址值、yeTing 保存的是 Person 對(duì)象在堆空間的地址值)

3. 對(duì)象中的方法存儲(chǔ)在那兒?

看下面的代碼,思考對(duì)象中的方法存儲(chǔ)在那兒?

public class Dog {
    public int price;

    public void run() {
        System.out.println(price + "_" + "run()");
    }

    public void eat() {
        System.out.println(price + "_" + "eat()");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.price = 255;
        dog1.run();
        dog1.eat();

        Dog dog2 = new Dog();
        dog2.price = 552;
        dog2.run();
        dog2.eat();
    }
}

Java 虛擬機(jī)執(zhí)行 Java 程序時(shí)會(huì)把內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域,主要包括:

  • ①  PC 寄存器(Program Counter Register):存儲(chǔ) Java 虛擬機(jī)正在執(zhí)行的字節(jié)碼指令的地址
  • Java 虛擬機(jī)棧(Java Virtual Machine Stack):存儲(chǔ) Java 方法的棧幀(① 方法被調(diào)用的時(shí)候會(huì)在??臻g創(chuàng)建該方法的棧幀,該方法執(zhí)行完畢后,該方法對(duì)應(yīng)的棧幀會(huì)銷毀;② 棧幀中會(huì)存放方法中的局部變量信息)【??臻g】
  • ③  堆空間(Heap):存儲(chǔ)被 GC(垃圾回收器) 所管理的各種對(duì)象(GC 管理的是通過 new 關(guān)鍵字創(chuàng)建的對(duì)象)
  • ④  方法區(qū)(Method Area):存儲(chǔ)每個(gè)類的結(jié)構(gòu)信息(如:字段和方法信息、構(gòu)造方法和普通方法的字節(jié)碼信息)
  • 本地方法棧(Native Method Stack):用來支持 native 方法的調(diào)用(如:用 C 語言編寫的方法)

4. Java 對(duì)象在內(nèi)存中的存在形式 ②

String:

  • 是字符串,在 Java 編程中被頻繁地使用,但它是引用類型
  • Java 中雙引號(hào)包裹的內(nèi)容默認(rèn)就是字符串類型
  • Java 中被雙引號(hào)包裹的內(nèi)容叫做字符串常量
  • 字符串常量存儲(chǔ)在字符串常量池中(String Constant Pool)
  • jdk1.7 之前,字符串常量池在方法區(qū);后來被移動(dòng)到了堆空間。所以,jdk1.8的字符串常量存儲(chǔ)在堆空間的字符串常量池中
  • 后面學(xué)習(xí) String 的時(shí)候還會(huì)細(xì)說

分析下面代碼的內(nèi)存布局:

public class Dog {
    String name;
    int age;
    String color;
}
public class DogDemo {
    public static void main(String[] args) {
        Dog doggy = new Dog();
        doggy.name = "笑天";
        doggy.age = 6;
        doggy.color = "黑";
    }
}

三、類中屬性詳細(xì)說明

  •  現(xiàn)實(shí)世界中的對(duì)象有狀態(tài)(State)和行為(Behavior),面向編程中的對(duì)象有屬性(Field)和方法(Method)。
  •  類是創(chuàng)建單個(gè)對(duì)象的藍(lán)圖(模板)

下面詳細(xì)說明一下類中【屬性】這個(gè)概念。其實(shí)上篇文章已經(jīng)能夠很好理解,這里只是再補(bǔ)充一下而已。

  • 屬性、成員變量、字段(field)指的是同一個(gè)東西(即一個(gè)類的狀態(tài))習(xí)慣上把現(xiàn)實(shí)世界的對(duì)象的狀態(tài)(State)和編程中的屬性聯(lián)系在一起,便于理解
  • 屬性可以是基本數(shù)據(jù)類型或引用類型(自定義類,接口,數(shù)組 …)
  • 定義屬性的語法:訪問修飾符 + 屬性類型(eg: String、int、Dog、Bicycle) + 屬性名
  • 訪問修飾符(控制屬性被訪問的范圍)有四種:public、protected、默認(rèn)(不寫)、private【后面會(huì)詳細(xì)說】
/**
 * 訪問修飾符有四種:public、protected、默認(rèn)(不寫)、private
 */
public class Dog {
    public String name;
    protected int age;
    String color;
    private double weight;
}

如果不給對(duì)象的屬性賦值,屬性會(huì)有初始值

/**
 * 測(cè)試若不給對(duì)象的屬性賦初始值, 它們的默認(rèn)初始值
 */
public class FiledInitialValueTest {
    private int score;
    private short age;
    private byte month;
    private long salary;
    private float height;
    private double pi;
    private char firstName;
    private boolean isTrueLove;
    private Person person;

    public static void main(String[] args) {
        FiledInitialValueTest test = new FiledInitialValueTest();
        System.out.println("\n若不給對(duì)象的屬性賦值, 初始值如下所示:");
        System.out.println("score【int】 = " + test.score);
        System.out.println("age【short】 = " + test.age);
        System.out.println("month【byte】 = " + test.month);
        System.out.println("salary【long】 = " + test.salary);
        System.out.println("height【float】 = " + test.height);
        System.out.println("pi【double】 = " + test.pi);
        // 字符類型的屬性的初始值是空串(在控制臺(tái)無法看到)
        System.out.println("firstName【char】 = " + test.firstName);
        // 字符類型的屬性的初始值強(qiáng)制類型轉(zhuǎn)換為 int 后是【0】
        System.out.println("firstName【(int)char】 = " + (int) test.firstName);
        System.out.println("isTrueLove【boolean】 = " + test.isTrueLove);
        System.out.println("person【person】 = " + test.person);
    }
}

四、細(xì)小知識(shí)點(diǎn)

1. 如何創(chuàng)建對(duì)象

必須先有類(模板)才能創(chuàng)建對(duì)象

通過【new】關(guān)鍵字創(chuàng)建類的對(duì)象?!緉ew】:向堆空間申請(qǐng)一塊內(nèi)存存儲(chǔ)對(duì)象數(shù)據(jù)

public class TestCreateObject {
    public static void main(String[] args) {
        // (1) 先聲明再創(chuàng)建
        Dog dog; // 聲明 
        dog = new Dog(); // 通過 new 關(guān)鍵字創(chuàng)建對(duì)象

        // (2) 聲明并創(chuàng)建對(duì)象 
        Dog doggy = new Dog();
    }
}

2. 如何訪問屬性

可通過【.】號(hào)訪問屬性或調(diào)用方法

可把 . 看做【的】、【の】

五、Exercise

看代碼,畫圖:

public class Person {
    private int age;
    private String name;

    public static void main(String[] args) {
        Person yangJiaLi = new Person();
        yangJiaLi.age = 17;
        yangJiaLi.name = "楊嘉立";

        // 下面的一行代碼有2種說法:
        // 1. 把 yangJiaLi 賦值給 yjl
        // 2. yjl 指向 yangJiaLi
        Person yjl = yangJiaLi;
        System.out.println(yjl.age); // 17
    }
}

六、總結(jié)

本篇文章的重點(diǎn)是第二節(jié)【Java 對(duì)象在內(nèi)存中的存在形式】

需重點(diǎn)知道:

到此這篇關(guān)于Java 對(duì)象在 JVM 中的內(nèi)存布局超詳細(xì)解說的文章就介紹到這了,更多相關(guān)Java JVM 內(nèi)存布局內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • RabbitMQ?延遲隊(duì)列實(shí)現(xiàn)訂單支付結(jié)果異步階梯性通知(實(shí)例代碼)

    RabbitMQ?延遲隊(duì)列實(shí)現(xiàn)訂單支付結(jié)果異步階梯性通知(實(shí)例代碼)

    這篇文章主要介紹了RabbitMQ?延遲隊(duì)列實(shí)現(xiàn)訂單支付結(jié)果異步階梯性通知,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • Java利用Selenium操作瀏覽器的示例詳解

    Java利用Selenium操作瀏覽器的示例詳解

    本文主要介紹如何使用java代碼利用Selenium操作瀏覽器,某些網(wǎng)頁元素加載慢,如何操作元素就會(huì)把找不到元素的異常,此時(shí)需要設(shè)置元素等待,等待元素加載完,再操作,感興趣的可以了解一下
    2023-01-01
  • Java多線程Thread類的使用詳解

    Java多線程Thread類的使用詳解

    這篇文章主要介紹了Java多線程Thread類的使用及注意事項(xiàng),在java標(biāo)準(zhǔn)庫中提供了一個(gè)Thread類來表示/操作線程,Thread類也可以視為是java標(biāo)準(zhǔn)庫提供的API
    2022-12-12
  • SSH框架網(wǎng)上商城項(xiàng)目第1戰(zhàn)之整合Struts2、Hibernate4.3和Spring4.2

    SSH框架網(wǎng)上商城項(xiàng)目第1戰(zhàn)之整合Struts2、Hibernate4.3和Spring4.2

    SSH框架網(wǎng)上商城項(xiàng)目第1戰(zhàn)之整合Struts2、Hibernate4.3和Spring4.2,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Mybatis中特殊SQL的執(zhí)行

    Mybatis中特殊SQL的執(zhí)行

    這篇文章主要介紹了Mybatis中特殊SQL的執(zhí)行,介紹內(nèi)容包括模糊查詢、批量刪除、動(dòng)態(tài)設(shè)置表名、添加功能獲取自增的主鍵等相關(guān)資料,需要的小伙伴可以參考一下
    2022-04-04
  • JMeter自定義日志與日志分析的實(shí)現(xiàn)

    JMeter自定義日志與日志分析的實(shí)現(xiàn)

    JMeter與Java程序一樣,會(huì)記錄事件日志,本文就介紹一下JMeter自定義日志與日志分析的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 的聲明詳解

    spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 的聲明詳解

    這篇文章主要給大家介紹了關(guān)于spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 聲明的相關(guān)資料,需要的朋友可以參考下
    2020-08-08
  • Java SpringMVC攔截器與異常處理機(jī)制詳解分析

    Java SpringMVC攔截器與異常處理機(jī)制詳解分析

    SpringMVC是一種基于Java,實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式,請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦?;谡?qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡(jiǎn)化開發(fā),SpringMVC也是要簡(jiǎn)化我們?nèi)粘eb開發(fā)
    2021-10-10
  • java如何對(duì)接企業(yè)微信的實(shí)現(xiàn)步驟

    java如何對(duì)接企業(yè)微信的實(shí)現(xiàn)步驟

    本文主要介紹了java如何對(duì)接企業(yè)微信的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Java中的設(shè)計(jì)模式與7大原則歸納整理

    Java中的設(shè)計(jì)模式與7大原則歸納整理

    本篇文章主要對(duì)Java中的設(shè)計(jì)模式如,創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式以及7大原則進(jìn)行了歸納整理,需要的朋友可以參考下
    2017-04-04

最新評(píng)論