Java基礎-方法區以及static的記憶體分配圖
前面的幾篇都沒有太明確地指出 方法區 是什麼?現在通過一些資料的收集和學習,下面做一些總結
什麼是方法區:
方法區是系統分配的一個記憶體邏輯區域,是JVM在裝載類檔案時,用於儲存型別資訊的(類的描述資訊)。
方法區存放的資訊包括:
類的基本資訊:
1.每個類的全限定名
2.每個類的直接超類的全限定名(可約束型別轉換)
3.該類是類還是介面
4.該型別的訪問修飾符
5.直接超介面的全限定名的有序列表
已裝載類的詳細資訊
1. 執行時常量池:在方法區中,每個型別都對應一個常量池,存放該型別所用到的所有常量,常量池中儲存了諸如文字字串、final變數值、類名和方法名常量。
2. 欄位資訊:欄位資訊存放類中宣告的每一個欄位的資訊,包括欄位的名、型別、修飾符。
3. 方法資訊:類中宣告的每一個方法的資訊,包括方法名、返回值型別、引數型別、修飾符、異常、方法的位元組碼。
(在編譯的時候,就已經將方法的區域性變數、運算元棧大小等確定並存放在位元組碼中,在裝載的時候,隨著類一起裝入方法區。)
4. 靜態變數:類變數,類的所有例項都共享,我們只需知道,在方法區有個靜態區,靜態區專門存放靜態變數和靜態塊。
5. 到類classloader的引用:到該類的類裝載器的引用。
6. 到類class 的引用:虛擬機器為每一個被裝載的型別建立一個class例項,用來代表這個被裝載的類。
下面分析static的記憶體分配
public class Dome_Static { public static void main(String[] args) { Person p1 = new Person(); p1.name = "xiaoming"; p1.country = "chinese"; Person p2 = new Person(); p2.name = "xiaohong"; p1.speak(); p2.speak(); } } class Person { String name; static String country; public void speak() { System.out.println("name:"+name+",country:"+country); } }
Output:
name:xiaoming,country:chinese
name:xiaohong,country:chinese
1.首先,先載入Dome_Static,然後其main函式入棧,之後Person被載入。static宣告的變數會隨著類的載入而載入,所以在記憶體中只會存在一份,例項化多個物件,都共享同一個static變數,會預設初始化
2.在棧記憶體為 p1 變數申請一個空間,在堆記憶體為Person物件申請空間,初始化完畢後將其地址值返回給p1,通過p1.name和p1.country修改其值
3.在棧記憶體為 p2 變數申請一個空間,在堆記憶體為Person物件申請空間,初始化完畢後將其地址值返回給p2,僅僅通過p2.name修改其值
4.列印show方法,進棧,這裡就不畫圖了,對於棧相關的概念不清楚的可以看看在之前發的部落格。簡單口述下:p1.show() show方法入棧,在方法的內部有個指向堆記憶體的this引用,通過該引用可找到堆記憶體實體,列印country時,可通過該堆記憶體物件找到對應的類,讀取對應靜態區中的欄位值
最後給大家一道面試題練練手,要求寫出其結果(筆試)
public class StaticTest {
public static int k = 0;
public static StaticTest t1 = new StaticTest("t1");
public static StaticTest t2 = new StaticTest("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("構造塊");
}
static{
print("靜態塊");
}
public StaticTest(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
++i;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
return ++n;
}
public static void main(String[] args) {
StaticTest t = new StaticTest("init");
}
}
結果:
1:j i=0 n=0
2:構造塊 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:構造塊 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:靜態塊 i=7 n=99
9:j i=8 n=100
10:構造塊 i=9 n=101
11:init i=10 n=102
這個留給大家去思考,如果一眼便能便知道為什麼是這樣的輸出結果,那麼靜態方面知識應該比較紮實了
提示一下 :
1.載入的順序:先父類的static成員變數 -> 子類的static成員變數 -> 父類的成員變數 -> 父類構造 -> 子類成員變數 -> 子類構造
2.static只會載入一次,所以通俗點講第一次new的時候,所有的static都先會被全部載入(以後再有new都會忽略),進行預設初始化。在從上往下進行顯示初始化。這裡靜態程式碼塊和靜態成員變數沒有先後之分,誰在上,誰就先初始化
3.構造程式碼塊是什麼?把所有構造方法中相同的內容抽取出來,定義到構造程式碼塊中,將來在呼叫構造方法的時候,會去自動呼叫構造程式碼塊。構造程式碼快優先於構造方法。
相關推薦
Java基礎-方法區以及static的記憶體分配圖
前面的幾篇都沒有太明確地指出 方法區 是什麼?現在通過一些資料的收集和學習,下面做一些總結 什麼是方法區: 方法區是系統分配的一個記憶體邏輯區域,是JVM在裝載類檔案時,用於儲存型別資訊的(類的描述資訊)。 方法區存放的資訊包括: 類的基本資訊: 1.每個類的全
Java系列之 方法區以及static的記憶體分配圖
轉載自: https://blog.csdn.net/Wang_1997/article/details/52267688 前面的幾篇都沒有太明確地指出 方法區 是什麼?現在通過一些資料的收集和學習,下面做一些總結 什麼是方法區: 方法區是系統分配
Java基礎知識回顧之static修飾方法
相關關鍵字的說明: this關鍵字 final關鍵字 static關鍵字修飾屬性 static關鍵字修飾方法 static關鍵字應用與總結 前面一篇已經介紹了部分關於 static 的用法,主要是介紹的是 static 修飾變數的一些知識。現在的這篇介紹下 static 修飾方法。
℃江的觀後感 -- Java 虛擬機器的方法區、直接記憶體和執行時常量池
方法區 我們知道方法區,當然是和方法有關,Java虛擬機器的作用就兩個,儲存、運算。其實我們叫其方法區,說明和儲存東西有關,但是存什麼呢?這塊儲存的是虛擬機器載入的類資訊,常亮,靜態變數和有個就是即使編譯後的程式碼等資料。方法區一般在hotspot被稱為永久代
Java基礎之final和static關鍵字
推薦 構造方法 其他 如果 靈活 位置 map 機制 lis 一、final 根據程序上下文環境,它可以修飾非抽象類、非抽象類成員方法和變量。 final類不能被繼承,沒有子類,final類中的方法默認是final的。 final
-Java基礎-方法
pla sso pue ant h5py lrn down splay clas 1.方法:方法就是對一片代碼包裝起來,給這片代碼按上一個名字。什麽時候用到這片代碼就調用這個名字就可以了。 1.方法必須申請在類中 2.方法中除了不能方法和類,其他想怎麽寫就這麽寫。 3.方
java虛擬機 jvm java堆 方法區 java棧
相同 分享 就會 例如 content == 不同的 avi 管理 java堆是java應用程序最密切的內存空間。差點兒全部的對象都存在堆中。java堆全然自己主動化管理,通過垃圾回收機制,垃圾對象會自己主動清理。不須要顯式釋放。 依據java垃圾回收機制的不同。
Java基礎——方法
方法方法在我們的日常生活中,會遇到各種各樣的問題,而我們需要尋求這些問題的解決辦法,也就是解決方法,所以方法在日常生活中也是無處不在的。在java中,我們去解決某個問題並找到這個問題的解決辦法就是方法。方法中封裝的是解決問題的具體代碼實現的功能,而我們只需要調用這個方法名就可以去解決這個問題。像之前學過的隨機
java基礎 方法
blog 類型 ron 使用方法 work 同名 垃圾回收器 程序計數器 ole 方法的定義和調用 方法定義,方法(Method),函數(function),其實就指一個特定的功能操作: 程序中完成獨立功能,可重復使用的一段代碼的集合; 方法定義格式: [修飾符]
Java基礎15-final、static關鍵字和Object類
不同 擁有 bsp 指數 col main hashcode 技術分享 fin 一、final關鍵字 1.什麽是final關鍵字 繼承的出現提高了代碼的復用性,並方便開發。但隨之也有問題,有些類在描述完之後,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。可
Java基礎-靜態代理以及動態代理
object 越來越大 耦合 返回 業務層 load 類加載 HA 目的 動態代理: 在了解動態代理之前,先對代理有一個認識. 代理模式是Java常見的設計模式之一。所謂代理模式是指客戶端並不直接調用實際的對象,而是通過調用代理,來間接的調用實際的對象。 打個比方:你買火車
C++基礎學習之類和動態記憶體分配(9)
主要學習內容: 對類成員使用動態記憶體分配。 隱式顯式複製建構函式。 隱式顯式過載賦值運算子。 在建構函式中使用new所必須完成的工作。 使用靜態類成員。 將定位new運算子用於物件。 使用指向物件的指標。 實現佇列抽象資料型別。(像第(
Java基礎語法 - 面向物件 - static 關鍵字
使用static關鍵字修飾的變數、常量和方法分別被稱作靜態變數、靜態常量和靜態方法,也被稱作類的靜態成員 靜態變數 使用static修飾過的類變數稱為靜態變數 該變數需要使用類名.變數名進行呼叫,不能使用物件名/this進行呼叫 在類方法中不能定義與靜態變數同名的區域性變數
JAVA基礎(49)---static及static修飾變數
static 所解決的問題 這裡摘錄一下《Java程式設計思想(第四版)》(《Java核心技術Ⅰ卷/Ⅱ卷》)裡關於static關鍵字的一段原話:(P29)通常來說,當建立類時,就是在描述那個類的物件的外觀與行為 。除非用new建立那個物件,否則,實際上並未獲得任何物件。執行new來建立物
16 Java基礎筆記-final、static關鍵字
關鍵字 一,final關鍵字 1,final概念 某些的類或者是類中部分的方法不想讓子類繼承重寫,使用關鍵字final修飾的物件不可被繼承,表示最終,不可變。可以用來修飾類,類成員,成員變數,區域性變數等。 2,final特點 1,final修飾類不可以被繼承,但可以繼承
JVM堆記憶體、方法區和棧記憶體的關係
以下程式碼展示Java堆記憶體、方法區和Java棧記憶體之間的關係 package cn.liang.jvm; public class SimpleHeap { private int id; public SimpleHeap(int id){ this.id = id;
Java基礎知識回顧之static應用與總結
相關關鍵字的說明: this關鍵字 final關鍵字 static關鍵字修飾屬性 static關鍵字修飾方法 static關鍵字應用與總結 前面兩篇分別介紹了static的屬性以及方法。本篇就做一個收尾,介紹下剩下的。 在之前的總結: 不管多少個物件,都使用同一個 s
Java基礎知識回顧之static修飾屬性
相關關鍵字的說明: this關鍵字 final關鍵字 static關鍵字修飾屬性 static關鍵字修飾方法 static關鍵字應用與總結 static 關鍵字,我們在開發用的還是比較多的。在《Java程式設計思想》有下面一段話 static 方法就是沒有 this 的方
Java基礎:詳解static 關鍵字
1. 前言 前文中說到了static關鍵字,在Java中這是一個很重要的關鍵字,它有很多的用法,並且在某些特定的情況下使用可以優化程式的效能。本文學習static關鍵字的應用場景。在這之前瞭解變數的型別,變數按作用域分為成員變數和區域性變數,成員變數也就是全域性變數,它是在類中宣告的,不
java基礎(四)static修飾類
在前面的部落格中,談到了static修飾類內部變數及程式碼塊的用法,卻忽略了其用來修飾內部類的情況。 為何會有用來修飾類的用法,及所有static用法的本質是什麼?這篇文章就解釋著兩個問題。 一、內部類 如果一個類要被宣告為static的,只有一種情況,就是靜態內部類。如果在外部類宣告為