Java面向?qū)ο蠛蛢?nèi)存分析圖文詳解
一、Java類
類是面向?qū)ο缶幊讨凶罨镜膯挝弧?/p>
Java中的類包含三個內(nèi)容,分別是:
屬性
- 屬性又叫成員變量。
- 屬性用于定義類或類對象的數(shù)據(jù)(靜態(tài)特征)。
- 范圍為整個類體。
方法
- 方法用于定義類或類對象的行為特征(執(zhí)行動作)(動態(tài))。
- 方法類似于面向過程中的函數(shù),面向過程中的函數(shù)是最基本的單位;
- 而在面向?qū)ο笾?,最基本單位是類,方法從屬于類和對象?br />
構(gòu)造方法
- 構(gòu)造方法分為無參構(gòu)造方法;有參構(gòu)造方法。
- 構(gòu)造方法要與類名保持一致。
- 如果不設(shè)置構(gòu)造方法,則系統(tǒng)自動生成無參構(gòu)造方法。
屬性的定義格式:
[修飾符] 屬性類型 屬性名 = [默認(rèn)值]; //若不初始化則系統(tǒng)默認(rèn)給默認(rèn)值
方法定義格式:
[修飾符] 方法返回值類型 方法名(形參){
語句
}
有如下代碼進(jìn)行示例分析
public class Person{ public String name; //屬性,帶有修飾符 int age; public void show(){ //方法 System.out.println("姓名:"+name+",年齡:"+age); } /* Person(){ //構(gòu)造方法,手動,無參構(gòu)造方法,一個類里無參構(gòu)造方法只能有一個 } */ /* Person(String name, int age){ //手動,有參構(gòu)造方法。 this.name = name; this.age = age; } */ public static void main (String[] args){ Person p1 = new Person("李四",18); //此時調(diào)用的是上面手動有參的構(gòu)造方法 Person p2 = new Person(); //此時調(diào)用的是無參構(gòu)造方法 p2.name = "張三"; //無參構(gòu)造方法需要以下賦值 p2.age = 18; p2.show(); } }
二、內(nèi)存分析
上面介紹了類的基本知識,那么我們接下來根據(jù)上面的代碼來進(jìn)行內(nèi)存分析。
JVM內(nèi)存模型很復(fù)雜,為了更好的理解面向?qū)ο蠛兔嫦驅(qū)ο蟠a,下面進(jìn)行對模型的簡化。(此內(nèi)存分析并不是為了理解JVM內(nèi)存模型)
下面對上面三個內(nèi)存模型進(jìn)行特征介紹:
棧:
- 棧描述的是方法執(zhí)行的內(nèi)存模型,每個方法被調(diào)用時都會創(chuàng)建一個棧幀。
- JVM為每個線程創(chuàng)建一個棧。
- 棧是私有,在線程間不會共享。
- 棧是一段連續(xù)的存儲空間。
堆:
- 堆用于存儲創(chuàng)建好的對象。
- JVM只有一個堆。
- 堆被所有線程共享。
- 堆是不連續(xù)的空間,分配靈活。
方法區(qū):
- 方法區(qū)實際也是堆,用來專門存儲類、常量(static關(guān)鍵詞相關(guān))等相關(guān)信息。
- JVM只有一個方法區(qū)。
- 可共享。
- 存儲不變的信息。
下面我們來看代碼的運行過程:
程序均是將main方法作為程序的入口,執(zhí)行第二條語句(第一條先忽略)
Person p2 = new Person();
此時會在棧中開辟一個新的棧幀,為main方法棧幀;方法區(qū)會加載整個類模板,存儲類里面的相關(guān)信息;在堆處會產(chǎn)生一個新的類的對象。如圖
/*
小插曲:Java使用new關(guān)鍵字來調(diào)用構(gòu)造方法,從而返回該類的實例(對象)。但是這個對象不是完全由構(gòu)造方法來創(chuàng)建的。創(chuàng)建一個方法分4步:在堆中分配對象空間,并將對象的成員變量初始化默認(rèn)值執(zhí)行顯式初始化(比如int i = 3)執(zhí)行構(gòu)造方法返回對象地址
*/
當(dāng)Person()構(gòu)造方法調(diào)用完成后,出棧繼續(xù)執(zhí)行main中的下一條語句。如圖
下一條語句是
p2.name = "張三"; p2.age = 18;
此時是方法區(qū)的張三賦值給name;
我們繼續(xù)執(zhí)行下條語句
p2.show();
此時會執(zhí)行show方法,我們注意到show方法中有age和name。那么它們是誰的name和age呢?我們可以看是p2.show()。p2的地址是0x11,指向的是堆中的0x11對象,所以show方法中的name和age就已知了。
那么當(dāng)方法執(zhí)行完后,show方法出棧,同時main方法也執(zhí)行完畢,也需要出棧,main方法執(zhí)行完后,對象和方法區(qū)中的類信息也就會清空。內(nèi)存就會回到最初的狀態(tài)。
總結(jié)
到此這篇關(guān)于Java面向?qū)ο蠛蛢?nèi)存分析的文章就介紹到這了,更多相關(guān)Java面向?qū)ο髢?nèi)存分析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Spring AOP實現(xiàn)MySQL數(shù)據(jù)庫讀寫分離案例分析(附demo)
分布式環(huán)境下數(shù)據(jù)庫的讀寫分離策略是解決數(shù)據(jù)庫讀寫性能瓶頸的一個關(guān)鍵解決方案,這篇文章主要介紹了使用Spring AOP實現(xiàn)MySQL數(shù)據(jù)庫讀寫分離案例分析(附demo),有興趣的可以了解一下。2017-01-01java中InputStream獲取字節(jié)大小相關(guān)方法詳解
這篇文章主要給大家介紹了關(guān)于java中InputStream獲取字節(jié)大小相關(guān)方法的相關(guān)資料,在Java中要實現(xiàn)讀取文件大小,可以使用InputStream來讀取文件的內(nèi)容,并通過獲取讀取的字節(jié)數(shù)來得到文件的大小,需要的朋友可以參考下2023-11-11Java ==,equals()與hashcode()的使用
本文主要介紹了Java ==,equals()與hashcode()的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05springboot接口多實現(xiàn)類選擇性注入解決方案
這篇文章主要為大家介紹了springboot接口多實現(xiàn)類選擇性注入解決方案的四種方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03java操作mongodb時,對象bean和DBObject相互轉(zhuǎn)換的方法(推薦)
下面小編就為大家?guī)硪黄猨ava操作mongodb時,對象bean和DBObject相互轉(zhuǎn)換的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11