簡體   English   中英

靜態方法的Java內存模型

[英]Java memory model for static methods

我來自C的操作系統和背景,那里的代碼編譯時世界很簡單。 需要處理和理解堆棧,堆文本部分等。

當我開始學習Java(我確實了解JVM和垃圾收集器)時,我對靜態方法感到很開心。 根據我的理解,一個類的所有實例都會在堆中創建,然后再清理。 但是,對於靜態方法,不需要類的實例。

因此,可以請一個人解釋一下非靜態方法和靜態方法在內存模型上的區別。 它們是否都位於內存的文本部分。 或者我完全搞砸了。

謝謝

在Java中,類的字節碼(包括它們的方法,包括靜態方法和實例方法)是堆的一部分(通常在長壽命對象的特殊“永久生成”部分中)。

類也可以被垃圾回收,但是這種情況通常不會發生太多(僅當從非系統類加載器加載該類並且整個類加載器變得過時(例如,當卸載Web應用程序時))。

但是,對於靜態方法,不需要類的實例。

對。 但是所有方法都是類定義的一部分,並且在加載類時一起加載。 即使您從未創建類的實例,所有實例方法的代碼也將加載到堆內存中。


然后,將JIT編譯為本地代碼:使用Hotspot,將常用方法的字節碼進一步編譯為本地機器代碼。 這樣的結果確實會在堆之外的某個地方進入本機內存,並且只會在實際使用的方法(靜態或非靜態)中發生。

您了解到類的所有實例都在堆中創建...

並非完全正確,所有類都被編譯為目標字節代碼,否則JVM沒有任何執行。 實例和靜態方法都生成相同的對象字節代碼。 甚至非靜態類也只生成其目標字節代碼的單個版本。 所有實例類都有自己的指針,指向它們在字節代碼的單個副本中執行的位置。 真正的區別在於類的數據成員。 非靜態類的每個實例必須具有所有非靜態數據成員(變量)的自己的副本,但是靜態數據成員在內存中僅具有單個副本,因為類的靜態數據成員由的所有實例共享。該類是靜態的還是非靜態的。

靜態類或非靜態類的靜態數據成員在內存中都具有自己的單個副本。

非靜態類在內存中仍然只有其目標代碼的一個副本,只有非靜態數據為每個實例在內存中獲取一個副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM