java中棧(stack)堆(heap)靜態區(static area)概念

2020-12-23 老徐聊java

對於java的這3大區域了解下還是有必要的,尤其是對jvm調優,更應該理解下它們的概念。

堆(heap):專門用來保存對象的實例(new 創建的對象和數組),實際上也只是保存對象實例的屬性值,屬性的類型和對象本身的類型標記等,並不保存對象的方法(方法是指令,保存在Stack中)。

存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令);jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身;一般由程式設計師分配釋放, 若程式設計師不釋放,程序結束時可能由OS回收。棧(stack):對象實例在heap 中分配好以後,需要在stack中保存一個4位元組的heap內存地址,用來定位該對象實例在heap 中的位置,便於找到該對象實例。

每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中;每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問;棧分為3個部分:基本類型變量區、執行環境上下文、操作指令區(存放操作指令);由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。靜態區(也叫方法區):跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量。

方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量;全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。

棧是運行時的單位,而堆是存儲時的單位

實際例子:String s1 = new String("China")

例子

對象本身存儲在堆中,常量存儲在靜態區,引用存儲在棧中。

為什麼把堆和棧區分出來呢?

第一:從軟體設計的角度看,棧代表了處理邏輯,而堆代表了數據。這樣分開,使得處理邏輯更為清晰。分而治之的思想。這種隔離、模塊化的思想在軟體設計的方方面面都有體現;

第二:堆與棧的分離,使得堆中的內容可以被多個棧共享(也可以理解為多個線程訪問同一個對象)。這種共享的收益是很多的。一方面這種共享提供了一種有效的數據交互方式(如:共享內存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節省了空間;

第三:棧因為運行時的需要,比如保存系統運行的上下文,需要進行地址段的劃分。由於棧只能向上增長,因此就會限制住棧存儲內容的能力。而堆不同,堆中的對象是可以根據需要動態增長的,因此棧和堆的拆分,使得動態增長成為可能,相應棧中只需記錄堆中的一個地址即可;

第四:面向對象就是堆和棧的完美結合。其實,面向對象方式的程序與以前結構化的程序在執行上沒有任何區別。但是,面向對象的引入,使得對待問題的思考方式發生了改變,而更接近於自然方式的思考。當我們把對象拆開,你會發現,對象的屬性其實就是數據,存放在堆中;而對象的行為(方法),就是運行邏輯,放在棧中。我們在編寫對象的時候,其實即編寫了數據結構,也編寫的處理數據的邏輯。

理解程序中每一個字符的存儲,才能為我們在jvm中調優做出依據,因為jvm調優也是相對的,解決了一個問題,必然會有第二個問題的潛伏,這就需要我們去衡量如何調優了(任何事情都是有利也有弊)

相關焦點

  • 深入分析Java中的關鍵字static
    對於這個概念,下面根據static關鍵字的四個基本使用來描述。然後在下一部分再來去分析static的原理,希望你能認真讀完。2、static關鍵字修飾類java裡面static一般用來修飾成員變量或函數。但有一種特殊用法是用static修飾內部類,普通類是不允許聲明為靜態的,只有內部類才可以。下面看看如何使用。
  • 親妹都能學會的 static 關鍵字
    s1 和 s2 這兩個引用變量存放在棧區(stack),沉默王二+18 這個對象和沉默王三+16 這個對象存放在堆區(heap),school 這個靜態變量存放在靜態區。」「等等,哥,棧、堆、靜態區?」三妹的臉上塞滿了疑惑。「哦哦,別擔心,三妹,畫幅圖你就全明白了。」
  • Java:故障排查、JVM性能監控工具單
    4、jmap:Java內存映像工具jamp命令用於生成堆轉儲快照。還可以查詢finalize執行隊列、Java堆和方法區的詳細信息,例如空間使用率、當前使用的是哪一種收集器等。to print java heap summary -histo[:live] to print histogram of java object heap; if the "live" suboption is specified, only count live objects -clstats
  • 想要面試BAT,做完這160道Java技術面試題,讓你胸有成竹!
    9、解釋內存中的棧(stack)、堆(heap)和靜態區(static area)的用法。10、Math.round(11.5) 等於多少?Math.round(-11.5)等於多少?11、switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?12、用最有效率的方法計算2乘以8?
  • 10道經典java面試題,看不看,你決定!
    棧(stack)、堆(heap)和靜態區(static area)的用法答:通常我們定義一個基本數據類型的變量,一個對象的引用,還有就是函數調用的現場保存都使用內存中的棧空間;而通過new關鍵字和構造器創建的對象放在堆空間;程序中的字面量(literal)如直接書寫的100、」hello」和常量都是放在靜態區中。
  • StackOverflow 上面最流行的 7 個 Java 問題!
    StackOverflow上的一個回答者,連結:http://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array/11227902#11227902試圖使用鐵路和火車來簡單介紹這個概念。
  • 深入分析Java虛擬機堆和棧及OutOfMemory異常產生原因
    所以GC也主要是回收堆中的對象實例,我們平常討論垃圾回收主要也是回收堆內存。堆可以處於物理上不連續的內存空間,可以固定大小,也可以動態擴展,通過參數-Xms和Xmx兩個參數來控制堆內存的最小和最大值。;import java.util.List;public class Heap {public static void main(String[] args) {List<Integer> list = new ArrayList
  • 普通Java程式設計師學習使用的6個JDK內建工具
    2、jhatJava堆分析工具(jhat)正如它名字描述的那樣:分析dump堆信息。在下面的小例子裡,我們構造了一個 OutOfMemoryError ,然後給這個 java 進程指定 -XX:+HeapDumpOnOutOfMemoryError ,這樣運行時就會產生一個 dump 文件供我們分析。
  • StackOverflow 上面最流行的 7 個 Java 問題!| 值得一看
    試圖使用鐵路和火車來簡單介紹這個概念。二、Java中的安全問題連結:http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords-in-java另一個流行的Java問題是:為什麼在Java中有關密碼的地方更加喜歡使用
  • Java面試寶典---Java基礎部分(7)
    和stack有什麼區別。java的內存分為兩類,一類是棧內存,一類是堆內存。棧內存是指程序進入一個方法時,會為這個方法單獨分配一塊私屬存儲空間,用於存儲這個方法內部的局部變量,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。堆是與棧作用不同的內存,一般用於存放不放在當前方法棧中的那些數據,例如,使用new創建的對象都放在堆裡,所以,它不會隨方法的結束而消失。
  • 某團面試題:JVM 堆內存溢出後,其他線程是否可繼續工作?
    由於題目中給出的OOM,java中OOM又分很多類型;比如:堆溢出(「java.lang.OutOfMemoryError: Java heap space」)、永久帶溢出(「java.lang.OutOfMemoryError:Permgen space」)、不能創建線程(「java.lang.OutOfMemoryError:Unable to create new native
  • Java 刷題必須了解的 API
    排序1.1 數組排序(`java.util.Arrays`)1.1.1 基本數據類型排序public static void sort(int[] a);> list);1.3 二維數組排序(`java.util.Arrays`)提示:Java 數組也是一種對象
  • Java 拷貝,你能說出個 123 麼?
    Java 基本複製方法java賦值是複製對象引用,如果我們想要得到一個對象的==副本==,使用賦值操作是無法達到目的的:修改新對象的值會同時修改舊對象的值。基本類型和引用類型這裡再給大家普及一個概念,在 Java 中基本類型和引用類型的區別。在 Java 中數據類型可以分為兩大類:基本類型和引用類型。
  • Stackoverflow問答:Java是傳值還是傳引用?
    來自:並發編程網 - ifeve.com原文:http://stackoverflow.com
  • 每日一課 | Java Static關鍵字示例
    static關鍵字可確保在內存中僅創建一個相關方法,對象或變量的實例。當需要一個類級別的變量來管理某些屬性值時,以及需要一個類級別的方法來執行某些操作時,都可以使用它。下面每個內容中都會詳細討論static關鍵字的使用。1. STATIC關鍵字作為變量修飾符當將static關鍵字用於變量時,它指示每個類僅應實例化一個變量。
  • Java面試題
    * During VM initialization, java.lang.Integer.IntegerCache.high property     * may be set and saved in the private system properties in the     * sun.misc.VM class.     */    private static class
  • JAVA中synchronized與static synchronized 的區別
    那麼static synchronized恰好就是要控制類的所有實例的訪問了,static synchronized是限制線程同時訪問jvm中該類的所有實例同時訪問對應的代碼快。          一個日本作者-結成浩的《java多線程設計模式》有這樣的一個列子: pulbic class Something(){     publicsynchronizedvoid isSyncA(){}     publicsynchronizedvoid isSyncB(){}     publicstaticsynchronizedvoid