當前位置:首頁 » 存儲配置 » 成員變數存儲在

成員變數存儲在

發布時間: 2023-11-01 11:20:22

java中成員變數都儲存在棧內存中嗎

一個完整的Java程序運行過程會涉及以下內存區域:x0dx0a寄存器:JVM內部虛擬寄存器,存取速度非常快,程序不可控制。x0dx0a棧:保存局部變數的值,包括:1.用來保存基本數據類型的值;2.保存類的實例,即堆區對象的引用(指針)。也可以用來保存載入方法時的幀。x0dx0a堆:用來存放動態產生的數據,比如new出來的對象。注意創建出來的對象只包含屬於各自的成員變數,並不包括成員方法陵猛。因為同一個類的對象擁有各自的成員變數,存儲在各自的堆中,但是他們共享該類的方法,並不是每創建一個對象就把成員方法復制一次。x0dx0a常量池:JVM為每個已載入的類型維護一個常量池,常量池就是這個類型用到的常量的一個尺冊橋有序集合。包括直接常量(基本類型,String)和對其他類型、方法、欄位的符號引用。池中的數據和數組一樣通過索引訪問。由於常量池包含了一個類型所有的對其他類型、方法、欄位的符號引用,所以常量池在Java的動態鏈接中起了核心作用。常量池存在於堆中。x0dx0a代碼段:用來存放從硬碟上讀取的源程序代碼。x0dx0a數據段:用來存放static定義的靜態成員。x0dx0ax0dx0a對於局部變數,如果是基本類型,會把值直接存儲在棧;如果是引用類型,比如String s = new String("william");會把其對象存儲在堆姿神,而把這個對象的引用(指針)存儲在棧。x0dx0a再如x0dx0aString s1 = new String(「william」);x0dx0aString s2 = s1;x0dx0as1和s2同為這個字元串對象的實例,但是對象只有一個,存儲在堆,而這兩個引用存儲在棧中。x0dx0ax0dx0a類的成員變數在不同對象中各不相同,都有自己的存儲空間(成員變數在堆中的對象中),基本類型和引用類型的成員變數都在這個對象的空間中,作為一個整體存儲在堆。而類的方法卻是該類的所有對象共享的,只有一套,對象使用方法的時候方法才被壓入棧,方法不使用則不佔用內存。

Ⅱ java語言中,類的成員變數分配在哪個內存區

成員變數有靜態和非靜態,靜態成員變數是共享數據,在共享區中,也叫方法區中。
非靜態成員變數在堆內存中,作用於整個類中。
而局部變數在棧內存中,定義在函數中,函數結束內存釋放。

Ⅲ 第五篇:IOS類探究(成員變數值放在哪裡,成員變數信息放在哪裡)

我們簡單寫個demo,在我們定義的類HPWPerson里放了name,age屬性,還有_hobby成員變數

首先我們考慮兩個問題,類方法是放在哪裡?成員變數是放在哪裡?帶著這兩個問題我們進行深入的探究下。

我們通過上篇結尾的分析其實知道,實例方法,成員屬性,協議等都是存放在class_rw_t這個結構體里,如下面源碼所示,

我們繼續在class_rw_t結構體源碼里找下,發現有class_ro_t這個結構體,這個結構體是干什麼的呢?

我們通過列印得到如下:

@property (nonatomic ,) NSString *name;這個會生成下劃線的成員變數_name,
@property (nonatomic ,assign) int age;這個會生成下劃線的成員變數_age,
發現我們再列印class_ro_t里發現有上圖所示的成員變數,所以其中「_hobby」,「_age」,"_name"這些是存在class_ro_t這個結構里的。

通過上面我們發現,成員變數的值是放在對象里,成名變數名字以及一些大小信息放在類裡面,這個是為什麼呢?其實類裡面的結構體它就好比山坦一個模板,通過這個模板就可以生成各個成員變數信息,但是成員變數的值是不同的所以成員變數的值要存放在實例對象里,成員變數名及大小信息放在類裡面就可以。

接著我們再繼續探究下,在class_rw_t這個結構體里有class_ro_t這個結構體,那這兩個結構體有什麼關系呢?

1.class_ro_t是在編譯的時候生成的(只讀),是一個純凈的空間,不能被修改的

我們知道蘋果的runtime可以動態的修改屬性和方法,但是ro里又不支持修改的,那它是如何實現的呢?
我們先看下WWDC里的一個視頻講解:
WWDC講解ro,rw鏈接

通過上面的視頻我罩唯舉們知道,ro在編譯的時候生成,在內存不夠的時候就會進行移除,當要使用的時候就會重新從磁碟里去載入。在objc源碼里我們發現有個叫class_rw_ext_t的結構體,簡稱為rwe。class_rw_ext_t這個也不是每個類里都生成的,因為生成class_rw_ext_t是有條件的:或者有分類,或者runtime API修改的時候會生成這個rwe結構體。runtime是無法修改成員變數的,rwe在對ro里進行拷貝出的也是其中一部分,一般ro里也就10%的內容需要修改。接著我們看rwe源碼如下,也驗證了我們這點:如果有rwe就直接返回裡面的methods,沒有就返回ro里的baseMethods。

屬性存放在rw里源碼:如果有rwe就直接返回裡面的properties,沒有就返回ro里的baseProperties。

協議存放在rw里源碼:如果有rwe就直接返回裡面的protocols,沒有就返回ro里的baseProtocols。

設計元類只是單獨為了存放我們的類方法嗎?

其實其目的是為了復用消息機制。在OC中調⽤⽅法,其實是在給某個對象發送某條消息。
消息的發送在編譯的時候編譯器就會把⽅法轉換為objc_msgSend這個函數。
id objc_msgSend(id self, SEL op, ...) 這個函數有倆個隱式的參數:消息的接收者,消息的⽅法
名。通過這倆個參數就能去找到對應⽅法的實現。
objc_msgSend函數就會通過第⼀個參數消息的接收者的isa指針,找到對應的類,如果我們是通過
實例對象調⽤⽅法,那麼這個isa指針就會找到實例對象的類對象,如果是類對象,就會找到類對
象的元類對象,然後再通過SEL⽅法名找到對應的imp,然後就能找到⽅法對應的實現。
那如果沒有元類的話,那這個objc_msgSend⽅法還得多加倆個參數,⼀個參數⽤來判斷這個⽅法
到底是類⽅法還是實例⽅法。⼀個參數⽤來判斷消息的接受者到底是類對象還是實例對象。
消息的發送,越快越好。那如果沒物碧有元類,在objc_msgSend內部就會有有很多的判斷,就會影響
消息的發送效率。
所以元類的出現就解決了這個問題,讓各類各司其職,實例對象就⼲存儲屬性值的事,類對象存儲
實例⽅法列表,元類對象存儲類⽅法列表,符合設計原則中的單⼀職責,⽽且忽略了對對象類型的
判斷和⽅法類型的判斷可以⼤⼤的提升消息發送的效率,並且在不同種類的⽅法⾛的都是同⼀套流
程,在之後的維護上也⼤⼤節約了成本。
所以這個元類的出現,最⼤的好處就是能夠復⽤消息傳遞這套機制。不管你是什麼類型的⽅法,都
是同⼀套流程。

接著我們如何證明我們上面所說的呢?下面我們來看下在源碼里設置斷點調試:

首先我們打開objc的源碼,

我們一直按上面去列印,最後會列印一個classMethod這個類方法,在我們設置HPWPerson這個類里也有這個方法,如下,所以證明了類方法是存放在元類裡面的。

接著我們看些runtime的api方法的實現:

上面這些我們是用runtime的api把成員變數,實例方法,類方法等列印出來。
通過上面總結:
1)ro里存放成員變數,實例方法,屬性,協議,類對象
2)類方法存放在元類裡面

Ⅳ Java中成員變數分配在哪個空間

變數分為成員變數和局部變數;
成員變數又分為實例變數和靜態變數;
實例變數在對象創建的時候分配內存空間,存儲在堆內存中;
靜態變數在類載入的時候分配內存空間,存儲在元空間;
局部變數在方法執行時分配內存空間,存儲在棧內存中。

熱點內容
龍村m腳本 發布:2024-11-29 17:38:10 瀏覽:781
linuxc配置文件 發布:2024-11-29 17:08:31 瀏覽:826
wow刷碎片腳本 發布:2024-11-29 15:58:24 瀏覽:591
明小子源碼 發布:2024-11-29 15:15:30 瀏覽:144
蘋果8plus什麼配置 發布:2024-11-29 14:16:36 瀏覽:677
androidmvp結構 發布:2024-11-29 14:16:34 瀏覽:536
androidsqlite命令 發布:2024-11-29 14:04:38 瀏覽:156
信用卡分期演算法 發布:2024-11-29 13:50:56 瀏覽:808
安卓手機dll文件為什麼打不開 發布:2024-11-29 13:40:49 瀏覽:1003
百分之五十石碳酸怎麼配置 發布:2024-11-29 13:38:56 瀏覽:974