深入理解java虛擬機之方法區(java虛擬機規範 豆瓣)

本文目錄一覽:

什麼是Java虛擬機?

虛擬機是一種抽象化的計算機,通過在實際的計算機上模擬模擬各種計算機功能來實現的。

Java虛擬機有自己完善的硬體架構,如處理器、堆棧、寄存器等,還具有相應的指令系統。JVM屏蔽了與具體操作系統平台相關的信息,使得Java程序只需生成在Java虛擬機上運行的目標代碼(位元組碼),就可以在多種平台上不加修改地運行。

這種解釋應該算是正確的,但是只描述了虛擬機的外部行為和功能,並沒有針對內部原理做出說明。一般情況下我們不需要知道虛擬機的運行原理,只要專註寫java代碼就可以了,這也正是虛擬機之所以存在的原因–屏蔽底層操作系統平台的不同並且減少基於原生語言開發的複雜性,使java這門語言能夠跨各種平台(只要虛擬機廠商在特定平台上實現了虛擬機),並且簡單易用。這些都是虛擬機的外部特性,但是從這些信息來解釋虛擬機,未免太籠統了,無法讓我們知道內部原理。

從進程的角度解釋JVM

讓我們嘗試從操作系統的層面來理解虛擬機。我們知道,虛擬機是運行在操作系統之中的,那麼什麼東西才能在操作系統中運行呢?當然是進程,因為進程是操作系統中的執行單位。可以這樣理解,當它在運行的時候,它就是一個操作系統中的進程實例,當它沒有在運行時(作為可執行文件存放於文件系統中),可以把它叫做程序。

對命令行比較熟悉的同學,都知道其實一個命令對應一個可執行的二進位文件,當敲下這個命令並且回車後,就會創建一個進程,載入對應的可執行文件到進程的地址空間中,並且執行其中的指令。下面對比C語言和Java語言的HelloWorld程序來說明問題。

首先編寫C語言版的HelloWorld程序。

編譯C語言版的HelloWorld程序:

gcc HelloWorld.c -o HelloWorld

運行C語言版的HelloWorld程序:

zhangjg@linux:/deve/workspace/HelloWorld/src$ ./HelloWorld

hello world

gcc編譯器編譯後的文件直接就是可被操作系統識別的二進位可執行文件,當我們在命令行中敲下 ./HelloWorld這條命令的時候, 直接創建一個進程, 並且將可執行文件載入到進程的地址空間中, 執行文件中的指令。

作為對比, 我們看一下Java版HelloWord程序的編譯和執行形式。

首先編寫源文件HelloWord.java :

編譯Java版的HelloWorld程序:

運行Java版的HelloWorld程序:

zhangjg@linux:/deve/workspace/HelloJava/src$ java -classpath . HelloWorld

HelloWorld

從上面的過程可以看到, 我們在運行Java版的HelloWorld程序的時候, 敲入的命令並不是 ./HelloWorld.class 。 因為class文件並不是可以直接被操作系統識別的二進位可執行文件 。 我們敲入的是java這個命令。 這個命令說明, 我們首先啟動的是一個叫做java的程序, 這個java程序在運行起來之後就是一個JVM進程實例。

上面的命令執行流程是這樣的:

java命令首先啟動虛擬機進程,虛擬機進程成功啟動後,讀取參數「HelloWorld」,把他作為初始類載入到內存,對這個類進行初始化和動態鏈接(關於類的初始化和動態鏈接會在後面的博客中介紹),然後從這個類的main方法開始執行。也就是說我們的.class文件不是直接被系統載入後直接在cpu上執行的,而是被一個叫做虛擬機的進程託管的。首先必須虛擬機進程啟動就緒,然後由虛擬機中的類載入器載入必要的class文件,包括jdk中的基礎類(如String和Object等),然後由虛擬機進程解釋class位元組碼指令,把這些位元組碼指令翻譯成本機cpu能夠識別的指令,才能在cpu上運行。

從這個層面上來看,在執行一個所謂的java程序的時候,真真正正在執行的是一個叫做Java虛擬機的進程,而不是我們寫的一個個的class文件。這個叫做虛擬機的進程處理一些底層的操作,比如內存的分配和釋放等等。我們編寫的class文件只是虛擬機進程執行時需要的「原料」。這些「原料」在運行時被載入到虛擬機中,被虛擬機解釋執行,以控制虛擬機實現我們java代碼中所定義的一些相對高層的操作,比如創建一個文件等,可以將class文件中的信息看做對虛擬機的控制信息,也就是一種虛擬指令。

編程語言也有自己的原理, 學習一門語言, 主要是把它的原理搞明白。 看似一個簡單的HelloWorld程序, 也有很多深入的內容值得剖析。

JVM體系結構簡介

為了展示虛擬機進程和class文件的關係,特意畫了下面一張圖:

根據上圖表達的內容,我們編譯之後的class文件是作為Java虛擬機的原料被輸入到Java虛擬機的內部的,那麼具體由誰來做這一部分工作呢?其實在Java虛擬機內部,有一個叫做類載入器的子系統,這個子系統用來在運行時根據需要載入類。注意上面一句話中的「根據需要」四個字。在Java虛擬機執行過程中,只有他需要一個類的時候,才會調用類載入器來載入這個類,並不會在開始運行時載入所有的類。就像一個人,只有餓的時候才去吃飯,而不是一次把一年的飯都吃到肚子里。一般來說,虛擬機載入類的時機,在第一次使用一個新的類的時候。本專欄後面的文章會具體討論Java中的類載入器。

由虛擬機載入的類,被載入到Java虛擬機內存中之後,虛擬機會讀取並執行它裡面存在的位元組碼指令。虛擬機中執行位元組碼指令的部分叫做執行引擎。就像一個人,不是把飯吃下去就完事了,還要進行消化,執行引擎就相當於人的腸胃系統。在執行的過程中還會把各個class文件動態的連接起來。關於執行引擎的具體行為和動態鏈接相關的內容也會在本專欄後續的文章中進行討論。

我們知道,Java虛擬機會進行自動內存管理。具體說來就是自動釋放沒有用的對象,而不需要程序員編寫代碼來釋放分配的內存。這部分工作由垃圾收集子系統負責。

從上面的論述可以知道, 一個Java虛擬機實例在運行過程中有三個子系統來保障它的正常運行,分別是類載入器子系統, 執行引擎子系統和垃圾收集子系統。 如下圖所示:

虛擬機的運行,必須載入class文件,並且執行class文件中的位元組碼指令。它做這麼多事情,必須需要自己的空間。就像人吃下去的東西首先要放在胃中。虛擬機也需要空間來存放個中數據。首先,載入的位元組碼,需要一個單獨的內存空間來存放;一個線程的執行,也需要內存空間來維護方法的調用關係,存放方法中的數據和中間計算結果;在執行的過程中,無法避免的要創建對象,創建的對象需要一個專門的內存空間來存放。關於虛擬機運行時數據區的內容,也會出現在本專欄後續的文章中。虛擬機的運行時內存區大概可以分成下圖所示的幾個部分。(這裡只是大概劃分,並沒有劃分的很精細)

總結

寫到這裡,基本上關於我對java虛擬機的理解就寫完了。這篇文章的主題雖然是深入理解Java虛擬機,但是你可能感覺一點也不「深入」,也只是泛泛而談。我也有這樣的感覺。限於自己水平有限,也只能這樣了,要是想深入理解java虛擬機,強烈建議讀一下三本書:

《深入Java虛擬機》

《深入理解Java虛擬機JVM高級特性與最佳實踐》

《Java虛擬機規範》

其實我也讀過這幾本書,但是它們對虛擬機的解釋也是基於一個外部模型,而沒有深入剖析虛擬機內部的實現原理。虛擬機是一個大而複雜的東西,實現虛擬機的人都是大牛級別的,如果不是參與過虛擬機的實現,應該很少有人能把它參透。本專欄後面的一些文章也參考了這三本書, 雖然講解Java語法的書不計其數, 但是深入講解虛擬機的書, 目前為止我就見過這三本,並且網上的資料也不是很多。

最後做一個總結:

1 虛擬機並不神秘,在操作系統的角度看來,它只是一個普通進程。

2 這個叫做虛擬機的進程比較特殊,它能夠載入我們編寫的class文件。如果把JVM比作一個人,那麼class文件就是我們吃的食物。

3 載入class文件的是一個叫做類載入器的子系統。就好比我們的嘴巴,把食物吃到肚子里。

4 虛擬機中的執行引擎用來執行class文件中的位元組碼指令。就好比我們的腸胃,對吃進去的食物進行消化。

5 虛擬機在執行過程中,要分配內存創建對象。當這些對象過時無用了,必須要自動清理這些無用的對象。清理對象回收內存的任務由垃圾收集器負責。就好比人吃進去的食物,在消化之後,必須把廢物排出體外,騰出空間可以在下次餓的時候吃飯並消化食物。

擴展資料:

關於JAVA虛擬機的參數說明如下:

1、運行class文件

執行帶main方法的class文件,Java虛擬機[3] 命令參數行為:

java CLASS文件名

注意:CLASS文件名不要帶文件後綴.class

例如:

java Test

如果執行的class文件是帶包的,即在類文件中使用了:

package ;包名

那應該在包的基路徑下執行,Java虛擬機命令行參數:

java ;包名.CLASS文件名

例如:

PackageTest.java中,其包名為:com.ee2ee.test,對應的語句為:

package com.ee2ee.test;

PackageTest.java及編譯後的class文件PackageTest.class的存放目錄如下:

classes

|__com

|__ee2ee

|__test

|__PackageTest.java

|__PackageTest.class

要運行PackageTest.class,應在classes目錄下執行:

java com.ee2ee.test.PackageTest

2、運行jar文件中的class

原理和運行class文件一樣,只需加上參數-cp jar文件名;即可。

例如:執行test.jar中的類com.ee2ee.test.PackageTest,命令行如下:

java -cp test.jar com.ee2ee.test.PackageTest

3、顯示JDK版本信息

當一台機器上有多個jdk版本時,需要知道當前使用的是那個版本的jdk,使用參數-version即可知道其版本,命令行為:

java -version

4、增加虛擬機可以使用的最大內存

Java虛擬機可使用的最大內存是有限制的,預設值通常為64MB或128MB。

如果一個應用程序為了提高性能而把數據載入內存中而佔用較大的內存,比如超過了默認的最大值128MB,需要加大java虛擬機可使用的最大內存,否則會出現Out of Memory的異常。啟動java時,需要使用如下兩個參數:

-Xms java虛擬機初始化時使用的內存大小

-Xmx java虛擬機可以使用的最大內存

以上兩個命令行參數中設置的size,可以帶單位,例如:256m表示256MB

舉例說明:

java -Xms128m -Xmx256m …

表示Java虛擬機初始化時使用的內存為128MB,可使用的最大內存為256MB。

對於tomcat,可以修改其腳本catalina. sh(Unix平台)或catalina.bat(Windows平台),設置變數JAVA_OPTS即可,例如:

JAVA_OPTS=’-Xms128m -Xmx256m’

參考資料:百度百科-java虛擬機

java虛擬機三個邏輯區的作用

JVM裡面的內存大致可以分為三個區域:

方法區:這裡主要放的是類的類型信息,可以簡單的理解為我們編寫的java類在內存中的映射。此外還保存常量信息。

堆:放置對象的地方,JVM會根據方法區中的類型信息創建實例,這些實例就保存在堆中。

棧:方法調用的地方,每個方法調用都對應一個棧幀,方法的調用就形成了線程。

以上只是大致的區域,內部還有很多細節,最好能參考相關書籍。

菜鳥:剛學java,堆區,棧區,靜態區,代碼區,暈了!!!!!

程序運行時,我們最好對數據保存到什麼地方做到心中有數。特別要注意的是內在的分配,有六個地方都可以保存數據:

1、 寄存器。這是最快的保存區域,因為它位於和其他所有保存方式不同的地方:處理器內部。然而,寄存器的數量十分有限,所以寄存器是根據需要由編譯器分配。我們對此沒有直接的控制權,也不可能在自己的程序里找到寄存器存在的任何蹤跡。

2、 堆棧。駐留於常規RAM(隨機訪問存儲器)區域。但可通過它的「堆棧指針」獲得處理的直接支持。堆棧指針若向下移,會創建新的內存;若向上移,則會釋放那些內存。這是一種特別快、特別有效的數據保存方式,僅次於寄存器。創建程序時,java編譯器必須準確地知道堆棧內保存的所有數據的「長度」以及「存在時間」。這是由於它必須生成相應的代碼,以便向上和向下移動指針。這一限制無疑影響了程序的靈活性,所以儘管有些java數據要保存在堆棧里——特別是對象句柄,但java對象並不放到其中。

3、 堆。一種常規用途的內存池(也在RAM區域),其中保存了java對象。和堆棧不同:「內存堆」或「堆」最吸引人的地方在於編譯器不必知道要從堆里分配多少存儲空間,也不必知道存儲的數據要在堆里停留多長的時間。因此,用堆保存數據時會得到更大的靈活性。要求創建一個對象時,只需用new命令編製相碰的代碼即可。執行這些代碼時,會在堆里自動進行數據的保存。當然,為達到這種靈活性,必然會付出一定的代價:在堆里分配存儲空間時會花掉更長的時間

4、 靜態存儲。這兒的「靜態」是指「位於固定位置」。程序運行期間,靜態存儲的數據將隨時等候調用。可用static關鍵字指出一個對象的特定元素是靜態的。但java對象本身永遠都不會置入靜態存儲空間。

5、 常數存儲。常數值通常直接置於程序代碼內部。這樣做是安全的。因為它們永遠都不會改變,有的常數需要嚴格地保護,所以可考慮將它們置入只讀存儲器(ROM)。

6、 非RAM存儲。若數據完全獨立於一個程序之外,則程序不運行時仍可存在,並在程序的控制範圍之外。其中兩個最主要的例子便是「流式對象」和「固定對象」。對於流式對象,對象會變成位元組流,通常會發給另一台機器,而對於固定對象,對象保存在磁碟中。即使程序中止運行,它們仍可保持自己的狀態不變。對於這些類型的數據存儲,一個特別有用的技藝就是它們能存在於其他媒體中,一旦需要,甚至能將它們恢復成普通的、基於RAM的對象。

什麼是 Java 虛擬機?

您好,提問者:

  Java虛擬機簡稱JVM,它的作用如下:

  1、其實Java不可跨平台,真正實現跨平台的是JVM虛擬機。

  2、JVM其實就是一個編譯java、運行class的一個跟操作系統的一個軟體。

  3、JVM的作用只針對於Java,而系統中的東西與它無關。

  4、其實說白了就是一個軟體,就像VMware一樣。

Java虛擬機

一、什麼是Java虛擬機

Java虛擬機是一個想像中的機器,在實際的計算機上通過軟體模擬來實現。Java虛擬機有自己想像中的硬體,如處理器、堆棧、寄存器等,還具有相應的指令系統。

為什麼要使用Java虛擬機

Java語言的一個非常重要的特點就是與平台的無關性。而使用Java虛擬機是實現這一特點的關鍵。一般的高級語言如果要在不同的平台上運行,至少需要編譯成不同的目標代碼。而引入Java語言虛擬機後,Java語言在不同平台上運行時不需要重新編譯。Java語言使用模式Java虛擬機屏蔽了與具體平台相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(位元組碼),就可以在多種平台上不加修改地運行。Java虛擬機在執行位元組碼時,把位元組碼解釋成具體平台上的機器指令執行。 

2.誰需要了解Java虛擬機

Java虛擬機是Java語言底層實現的基礎,對Java語言感興趣的人都應對Java虛擬機有個大概的了解。這有助於理解Java語言的一些性質,也有助於使用Java語言。對於要在特定平台上實現Java虛擬機的軟體人員,Java語言的編譯器作者以及要用硬體晶元實現Java虛擬機的人來說,則必須深刻理解Java虛擬機的規範。另外,如果你想擴展Java語言,或是把其它語言編譯成Java語言的位元組碼,你也需要深入地了解Java虛擬機。

3.Java虛擬機支持的數據類型

Java虛擬機支持Java語言的基本數據類型如下:

byte://1位元組有符號整數的補碼

short://2位元組有符號整數的補碼

int://4位元組有符號整數的補碼

long://8位元組有符號整數的補碼

float://4位元組IEEE754單精度浮點數

double://8位元組IEEE754雙精度浮點數

char://2位元組無符號Unicode字元

幾乎所有的Java類型檢查都是在編譯時完成的。上面列出的原始數據類型的數據在Java執行時不需要用硬體標記。操作這些原始數據類型數據的位元組碼(指令)本身就已經指出了操作數的數據類型,例如iadd、ladd、fadd和dadd指令都是把兩個數相加,其操作數類型別是int、long、float和double。虛擬機沒有給boolean(布爾)類型設置單獨的指令。boolean型的數據是由integer指令,包括integer返回來處理的。boolean型的數組則是用byte數組來處理的。虛擬機使用IEEE754格式的浮點數。不支持IEEE格式的較舊的計算機,在運行Java數值計算程序時,可能會非常慢。

虛擬機支持的其它數據類型包括:

object//對一個Javaobject(對象)的4位元組引用

returnAddress//4位元組,用於jsr/ret/jsr-w/ret-w指令

注:Java數組被當作object處理。

虛擬機的規範對於object內部的結構沒有任何特殊的要求。在Sun公司的實現中,對object的引用是一個句柄,其中包含一對指針:一個指針指向該object的方法表,另一個指向該object的數據。用Java虛擬機的位元組碼錶示的程序應該遵守類型規定。Java虛擬機的實現應拒絕執行違反了類型規定的位元組碼程序。Java虛擬機由於位元組碼定義的限制似乎只能運行於32位地址空間的機器上。但是可以創建一個Java虛擬機,它自動地把位元組碼轉換成64位的形式。從Java虛擬機支持的數據類型可以看出,Java對數據類型的內部格式進行了嚴格規定,這樣使得各種Java虛擬機的實現對數據的解釋是相同的,從而保證了Java的與平台無關性和可

移植性。

二、Java虛擬機體系結構

Java虛擬機由五個部分組成:一組指令集、一組寄存器、一個棧、一個無用單元收集堆(Garbage-collected-heap)、一個方法區域。這五部分是Java虛擬機的邏輯成份,不依賴任何實現技術或組織方式,但它們的功能必須在真實機器上以某種方式實現。

Java指令集

Java虛擬機支持大約248個位元組碼。每個位元組碼執行一種基本的CPU運算,例如,把一個整數加到寄存器,子程序轉移等。Java指令集相當於Java程序的彙編語言。 

Java指令集中的指令包含一個單位元組的操作符,用於指定要執行的操作,還有0個或多個操作數,提供操作所需的參數或數據。許多指令沒有操作數,僅由一個單位元組的操作符構成。

虛擬機的內層循環的執行過程如下:

do{

取一個操作符位元組;

根據操作符的值執行一個動作;

}while(程序未結束)

由於指令系統的簡單性,使得虛擬機執行的過程十分簡單,從而有利於提高執行的效率。指令中操作數的數量和大小是由操作符決定的。如果操作數比一個位元組大,那麼它存儲的順序是高位位元組優先。例如,一個16位的參數存放時佔用兩個位元組,其值為:

第一個位元組*256+第二個位元組位元組碼指令流一般只是位元組對齊的。指令tabltch和lookup是例外,在這兩條指令內部要求強制的4位元組邊界對齊。

2.寄存器

Java虛擬機的寄存器用於保存機器的運行狀態,與微處理器中的某些專用寄存器類似。

Java虛擬機的寄存器有四種:

pc:Java程序計數器。

optop:指向操作數棧頂端的指針。

frame:指向當前執行方法的執行環境的指針。

vars:指向當前執行方法的局部變數區第一個變數的指針。

Java虛擬機

Java虛擬機是棧式的,它不定義或使用寄存器來傳遞或接受參數,其目的是為了保證指令集的簡潔性和實現時的高效性(特別是對於寄存器數目不多的處理器)。

所有寄存器都是32位的。

3.棧

Java虛擬機的棧有三個區域:局部變數區、運行環境區、操作數區。

(1)局部變數區 每個Java方法使用一個固定大小的局部變數集。它們按照與vars寄存器的字偏移量來定址。局部變數都是32位的。長整數和雙精度浮點數佔據了兩個局部變數的空間,卻按照第一個局部變數的索引來定址。(例如,一個具有索引n的局部變數,如果是一個雙精度浮點數,那麼它實際佔據了索引n和n+1所代表的存儲空間。)虛擬機規範並不要求在局部變數中的64位的值是64位對齊的。虛擬機提供了把局部變數中的值裝載到操作數棧的指令,也提供了把操作數棧中的值寫入局部變數的指令。

(2)運行環境區 在運行環境中包含的信息用於動態鏈接,正常的方法返回以及異常傳播。

·動態鏈接

運行環境包括對指向當前類和當前方法的解釋器符號表的指針,用於支持方法代碼的動態鏈接。方法的class文件代碼在引用要調用的方法和要訪問的變數時使用符號。動態鏈接把符號形式的方法調用翻譯成實際方法調用,裝載必要的類以解釋還沒有定義的符號,並把變數訪問翻譯成與這些變數運行時的存儲結構相應的偏移地址。動態鏈接方法和變數使得方法中使用的其它類的變化不會影響到本程序的代碼。

·正常的方法返回

如果當前方法正常地結束了,在執行了一條具有正確類型的返回指令時,調用的方法會得到一個返回值。執行環境在正常返回的情況下用於恢復調用者的寄存器,並把調用者的程序計數器增加一個恰當的數值,以跳過已執行過的方法調用指令,然後在調用者的執行環境中繼續執行下去。

·異常和錯誤傳播

異常情況在Java中被稱作Error(錯誤)或Exception(異常),是Throwable類的子類,在程序中的原因是:①動態鏈接錯,如無法找到所需的class文件。②運行時錯,如對一個空指針的引用

·程序使用了throw語句。

當異常發生時,Java虛擬機採取如下措施:

·檢查與當前方法相聯繫的catch子句表。每個catch子句包含其有效指令範圍,能夠處理的異常類型,以及處理異常的代碼塊地址。

·與異常相匹配的catch子句應該符合下面的條件:造成異常的指令在其指令範圍之內,發生的異常類型是其能處理的異常類型的子類型。如果找到了匹配的catch子句,那麼系統轉移到指定的異常處理塊處執行;如果沒有找到異常處理塊,重複尋找匹配的catch子句的過程,直到當前方法的所有嵌套的catch子句都被檢查過。

·由於虛擬機從第一個匹配的catch子句處繼續執行,所以catch子句表中的順序是很重要的。因為Java代碼是結構化的,因此總可以把某個方法的所有的異常處理器都按序排列到一個表中,對任意可能的程序計數器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計數器值下發生的異常情況。

·如果找不到匹配的catch子句,那麼當前方法得到一個”未截獲異常”的結果並返回到當前方法的調用者,好像異常剛剛在其調用者中發生一樣。如果在調用者中仍然沒有找到相應的異常處理塊,那麼這種錯誤傳播將被繼續下去。如果錯誤被傳播到最頂層,那麼系統將調用一個預設的異常處理塊。

(3)操作數棧區 機器指令只從操作數棧中取操作數,對它們進行操作,並把結果返回到棧中。選擇棧結構的原因是:在只有少量寄存器或非通用寄存器的機器(如Intel486)上,也能夠高效地模擬虛擬機的行為。操作數棧是32位的。它用於給方法傳遞參數,並從方法接收結果,也用於支持操作的參數,並保存操作的結果。例如,iadd指令將兩個整數相加。相加的兩個整數應該是操作數棧頂的兩個字。這兩個字是由先前的指令壓進堆棧的。這兩個整數將從堆棧彈出、相加,並把結果壓回到操作數棧中。

每個原始數據類型都有專門的指令對它們進行必須的操作。每個操作數在棧中需要一個存儲位置,除了long和double型,它們需要兩個位置。操作數只能被適用於其類型的操作符所操作。例如,壓入兩個int類型的數,如果把它們當作是一個long類型的數則是非法的。在Sun的虛擬機實現中,這個限制由位元組碼驗證器強制實行。但是,有少數操作(操作符dupe和swap),用於對運行時數據區進行操作時是不考慮類型的。

4.無用單元收集堆

Java的堆是一個運行時數據區,類的實例(對象)從中分配空間。Java語言具有無用單元收集能力:它不給程序員顯式釋放對象的能力。Java不規定具體使用的無用單元收集演算法,可以根據系統的需求使用各種各樣的演算法。

5.方法區

方法區與傳統語言中的編譯後代碼或是Unix進程中的正文段類似。它保存方法代碼(編譯後的java代碼)和符號表。在當前的Java實現中,方法代碼不包括在無用單元收集堆中,但計劃在將來的版本中實現。每個類文件包含了一個Java類或一個Java界面的編譯後的代碼。可以說類文件是Java語言的執行代碼文件。為了保證類文件的平台無關性,Java虛擬機規範中對類文件的格式也作了詳細的說明。其具體細節請參考Sun公司的Java虛擬機規範。

jvm Class對象的作用?

類是程序的一部分,每個類都有一個類對象。換句話說,無論何時編寫和編譯新類,都會生成一個Class對象(更恰當地說,保存在相同名稱的A.class文件中)。當第一次使用所有類時,它們都被動態地載入到JVM中。例如,我們編寫了一個Test類並編譯它來生成Test。班級。此時,Test類的Class對象保存在類文件中。當我們新建一個對象或引用一個靜態成員變數時,java虛擬機(JVM)中的類載入器子系統將相應的類對象載入到JVM中,然後JVM從這個類型的信息中創建我們需要的類對象,或者提供靜態變數的參考值。應當注意,無論創建了多少實例對象,手動編寫的每個類類類在JVM中都只有一個Class對象,也就是說,每個類在內存中都具有並且只有一個對應的Class對象。

1 Test t1 = new Test();

2 Test t2 = new Test();

3 Test t3 = new Test();

如上所示,實際上JVM內存中只存在一個Test的Class對象。

Class類,類類也是Java中存在的一個真實類。JDK的Lang軟體包。類類的實例表示Java應用程序運行時的類枚舉或介面和注釋(每個Java類運行時被表示為JVM中的類對象),類對象可以通過類名來獲得。類,類型。getClass(),Class.forName(「類名」)。數組還映射到一個類對象,該類對象由具有相同元素類型和維度的所有數組共享。基本類型布爾、位元組、char、.、int、long、float、double和關鍵詞void也表示為類對象。

原創文章,作者:SLSOG,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/128577.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
SLSOG的頭像SLSOG
上一篇 2024-10-03 23:25
下一篇 2024-10-03 23:25

相關推薦

  • ArcGIS更改標註位置為中心的方法

    本篇文章將從多個方面詳細闡述如何在ArcGIS中更改標註位置為中心。讓我們一步步來看。 一、禁止標註智能調整 在ArcMap中設置標註智能調整可以自動將標註位置調整到最佳顯示位置。…

    編程 2025-04-29
  • 解決.net 6.0運行閃退的方法

    如果你正在使用.net 6.0開發應用程序,可能會遇到程序閃退的情況。這篇文章將從多個方面為你解決這個問題。 一、代碼問題 代碼問題是導致.net 6.0程序閃退的主要原因之一。首…

    編程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一個類的構造函數,在創建對象時被調用。在本篇文章中,我們將從多個方面詳細討論init方法的作用,使用方法以及注意點。 一、定義init方法 在Pyth…

    編程 2025-04-29
  • Python創建分配內存的方法

    在python中,我們常常需要創建並分配內存來存儲數據。不同的類型和數據結構可能需要不同的方法來分配內存。本文將從多個方面介紹Python創建分配內存的方法,包括列表、元組、字典、…

    編程 2025-04-29
  • Python中讀入csv文件數據的方法用法介紹

    csv是一種常見的數據格式,通常用於存儲小型數據集。Python作為一種廣泛流行的編程語言,內置了許多操作csv文件的庫。本文將從多個方面詳細介紹Python讀入csv文件的方法。…

    編程 2025-04-29
  • 用不同的方法求素數

    素數是指只能被1和自身整除的正整數,如2、3、5、7、11、13等。素數在密碼學、計算機科學、數學、物理等領域都有著廣泛的應用。本文將介紹幾種常見的求素數的方法,包括暴力枚舉法、埃…

    編程 2025-04-29
  • 使用Vue實現前端AES加密並輸出為十六進位的方法

    在前端開發中,數據傳輸的安全性問題十分重要,其中一種保護數據安全的方式是加密。本文將會介紹如何使用Vue框架實現前端AES加密並將加密結果輸出為十六進位。 一、AES加密介紹 AE…

    編程 2025-04-29
  • Python學習筆記:去除字元串最後一個字元的方法

    本文將從多個方面詳細闡述如何通過Python去除字元串最後一個字元,包括使用切片、pop()、刪除、替換等方法來實現。 一、字元串切片 在Python中,可以通過字元串切片的方式來…

    編程 2025-04-29
  • 用法介紹Python集合update方法

    Python集合(set)update()方法是Python的一種集合操作方法,用於將多個集合合併為一個集合。本篇文章將從以下幾個方面進行詳細闡述: 一、參數的含義和用法 Pyth…

    編程 2025-04-29
  • Vb運行程序的三種方法

    VB是一種非常實用的編程工具,它可以被用於開發各種不同的應用程序,從簡單的計算器到更複雜的商業軟體。在VB中,有許多不同的方法可以運行程序,包括編譯器、發布程序以及命令行。在本文中…

    編程 2025-04-29

發表回復

登錄後才能評論