導航:首頁 > 安裝方法 > 類的成員方法存儲在哪裡

類的成員方法存儲在哪裡

發布時間:2023-03-26 20:38:33

① Java內存中沒有實例化一個類的時候,該類的成員變數放在哪對象又是怎麼引用方法的

java 講的是 面向燃激對象
一個類是一個對象
實例化一個類出來的對象是該類的引用 比如 A b = new A() b就是A的引用
A類的所有方法屬性 b 現在都可以使用了
你初學者不要先去管 堆棧的問題碼培 你現在主要搞清楚怎麼去皮模襪使用對象
所有非static 關鍵字 註明的時候 都在使用的時候加入內存當中的

② java的成員變數是存在於哪裡如果是堆中該如何回收呢,能用system.gc嗎

  1. Java成員變數存儲在堆中:創建出來的對象只包含屬於各自的成員變數,並不包含成員方法。同一個類對象擁有各自的成員變數,存儲在各自的堆中,但是他們共享該類的方法,並不是創建一個對象就把成員變數復制一次。

  2. 當一個對象(包括對象中的成員變數)沒有對象引用指向原先分配給某個對象的內存時,該內存便成為垃圾。JVM的一個系統級線程會自動釋放該內存塊,可以使用system.gc

③ JAVA中的類成員變數是存在堆還是棧裡面呀

類的成員變數都在堆上,只有方法裡面定義的基礎變數,在方法裡面定義的引用
其他對象的引用放在棧上(這個時候被引用的對象和它的成員變數還是在堆上)

也就是說,線程上下文的東西在棧上,其他統統在堆上。

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

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

⑤ C++類編譯好後,成員變數存儲在什麼位置代碼區

內存被他為棧區和堆區,程序的全局變數和局部變數這些數據是存放在棧中,因為一個子程序或函數調用結束後,函數或子程序使用的內存全被回收,這人實現的方法就是棧。函數在調用編譯器會在棧中分配足夠的空間,然後將數據全部壓入棧中,等調用結束會自動清空棧,這樣函數所使用的內存就消失了。
但我們知道動態內存是可以誇函數使用的,這是因為動態內存是分配在堆中,不受棧這個條件的限制,所以動態內存需要我們自己去釋放,如果我們自己不釋放就會造成內存泄漏,但操作系統會在程序結束後回收程序使用的所有內存。
至於代碼區,數據區,棧區,這些在8086中是很重要的,這是因為8086CPU的問題。現在的32位CPU和16位CPU在對這些區的定義不一樣。32位CPU可以不用去管這些區,但在進行32匯編時還是要需要,不同區會有不同的屬性,但對程序的整體影響不大。
建議你去看羅雲彬的win32匯編,這本書對這些說得很清楚,只是書有點厚,難懂。

⑥ 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中成員變數都儲存在棧內存中嗎

一個完整的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中,靜態方法被調用是,存儲在內存的哪個區域是棧還是放大區還是兩者都有

在JDK8之前,靜態成員(靜態變數和靜態方法)都是存儲在方法區(永久代)中的靜態區中(這里指類被載入後,靜態成員的存儲位置)。但在JDK8之後,永久代被移除了,取而代之的是元空間(metaspace)。但元空間中存儲的主要是.class文件的元數據信息,靜態成員的存儲位置由方法區轉到了堆內存(heap)中。
不過,不管是JDK8,還是更早的版本中,靜態方法的執行(不僅僅是靜態方法,還有普通的成員方法)都是在棧內存(stack)中進行的。每個線程都會在棧內存中開辟一個棧,在調用方法時,對應的方法都會在執行這個方法的線程的棧中創建一個「棧幀」,棧幀中保存了局部變數表(基本數據類型和對象引用)、操作數棧、動態連接和返回地址等信息。等到方法執行完畢,棧幀被銷毀,對應的內存也將被釋放。

閱讀全文

與類的成員方法存儲在哪裡相關的資料

熱點內容
核桃外皮食用方法 瀏覽:344
生杜仲的食用方法 瀏覽:962
計算機外部的編碼方法有哪些 瀏覽:519
idea查看哪裡調用方法 瀏覽:439
野山青葡萄簡單泡酒方法 瀏覽:335
怎麼方法快速去痘印 瀏覽:651
初學者數錢的方法視頻 瀏覽:379
阿富汗青玉鑒別最簡單方法 瀏覽:450
葡萄小苗修剪方法視頻 瀏覽:303
紅米手機濾鏡的使用方法 瀏覽:769
電動汽車正確充電方法 瀏覽:730
鑒別真假濕疣方法 瀏覽:469
人生迷茫的最佳解決方法 瀏覽:496
傷口的測量及記錄方法頭為坐標 瀏覽:913
行為護理干預方法有哪些 瀏覽:640
柴油車打齒圈解決方法 瀏覽:294
床氣壓桿安裝方法 瀏覽:708
急膽囊炎的治療方法 瀏覽:188
鞭腿的訓練方法 瀏覽:689
如何解釋教育方法 瀏覽:376