本文目錄一覽:
java編程原理(簡單的說一下)
Java的編程原理 編譯原理: 先寫Java的源代碼。 然後交給虛擬機 虛擬機將其編譯為 字節碼 然後再進行運行。 Java的編譯後的字節碼,不是成為機器碼。它必須要求有編譯器在旁解釋。 它是解釋型編譯編程原理: Java 主要面向OOP, Java 面向對象編程語言,基本上寫每個程序 都在面向整個世界的對象 而描寫,Java比你學過的C++ 更為靈活。比如接口、 或者你需要更多的答案。 請提問
你知道java的運行原理是什麼嗎
Java這一語言的執行過程也遵循這樣的過程:源代碼—機器碼。 但是,從源代碼到機器碼之間,究竟經過什麼樣的過程,則是Java獨一無二的了。寬泛地講,Java源代碼(.java)經過java編譯器(javac.exe)編譯之後,並沒有直接轉化為機器碼,而是轉化成一種中間格式,成為字節碼(.class),字節碼再經過java虛擬機轉化成特定CPU架構的機器碼。也正是因為這一中間物,java才有所謂的跨平台。在windows平台上編譯好的字節碼,copy到linux平台後,經過為linux而設計的Java虛擬機解釋後即可執行。跨平台這一特徵,是通過字節碼和JVM來實現的。
因此,想搞清楚java程序到底是如何運行的,重點在於弄明白字節碼是如何被轉化成跟CPU架構相關的機器碼然後被執行的。也就是要理解JVM到底是如何工作的。在了解JVM之前,我們再跳出來一下,先看看什麼是虛擬機。所謂虛擬機,我是這麼理解的:用軟件的方式模擬出跟硬件類似的環境,比如說寄存器、存儲器等等。當然,所有最終的工作還是由原來的CPU來完成。比如說VirtualBox這個虛擬機產品,它其實就是一個應用程序,用某種編程語言編寫的應用程序。當運行這個應用程序時,它會要求操作系統給它獨立施展手腳的空間:給我一些內存,給我一定的CPU時間片,然後不用管我了。你可能會問,寄存器是硬件啊,它怎麼能劃分啊,難道是時間劃分?不是的,像內存這樣的硬件,可以給虛擬機一塊獨立的內存塊,但是寄存器之後的,則需要用“模擬仿真”的方式來模擬。OK,回到Java虛擬機。到底什麼是Java虛擬機,很難有一個十分明確的定義,狹窄一點說,它就是一個應用程序,大部分用C++編寫的。寬泛地說,它就是執行字節碼的一整個環境。
java虛擬機工作原理?
從宏觀上介紹一下Java虛擬機的工作原理。從最初編寫的Java源文件(.java文件)是如何一步步執行的,如下圖所示,首先Java源文件經過前端編譯器(javac或ECJ)將.java文件編譯為Java字節碼文件,然後JRE加載Java字節碼文件,載入系統分配給JVM的內存區,然後執行引擎解釋或編譯類文件,再由即時編譯器將字節碼轉化為機器碼。主要介紹下圖中的類加載器和運行時數據區兩個部分。
(1)類加載指將類的字節碼文件(.class)中的二進制數據讀入內存,將其放在運行時數據區的方法區內,然後在堆上創建java.lang.Class對象,封裝類在方法區內的數據結構。類加載的最終產品是位於堆中的類對象,類對象封裝了類在方法區內的數據結構,並且向JAVA程序提供了訪問方法區內數據結構的接口。如下是類加載器的層次關係圖。
啟動類加載器(BootstrapClassLoader):在JVM運行時被創建,負責加載存放在JDK安裝目錄下的jre\lib的類文件,或者被-Xbootclasspath參數指定的路徑中,並且能被虛擬機識別的類庫(如rt.jar,所有的java.*開頭的類均被Bootstrap ClassLoader加載)。啟動類無法被JAVA程序直接引用。
擴展類加載器(Extension ClassLoader):該類加載器負責加載JDK安裝目錄下的\jre\lib\ext的類,或者由java.ext.dirs系統變量指定路徑中的所有類庫,開發者也可以直接使用擴展類加載器。
應用程序類加載器(AppClassLoader):負責加載用戶類路徑(Classpath)所指定的類,開發者可以直接使用該類加載器,如果應用程序中沒有定義過自己的類加載器,該類加載器為默認的類加載器。
用戶自定義類加載器(User ClassLoader):JVM自帶的類加載器是從本地文件系統加載標準的java class文件,而自定義的類加載器可以做到在執行非置信代碼之前,自動驗證數字簽名,動態地創建符合用戶特定需要的定製化構建類,從特定的場所(數據庫、網絡中)取得java class。
注意如上的類加載器並不是通過繼承的方式實現的,而是通過組合的方式實現的。而JAVA虛擬機的加載模式是一種委派模式,如上圖中的1-7步所示。下層的加載器能夠看到上層加載器中的類,反之則不行。類加載器可以加載類但是不能卸載類。說了一大堆,還是感覺需要拿點代碼說事。
首先先定義自己的類加載器MyClassLoader,繼承自ClassLoader,並覆蓋了父類的findClass(String name)方法,如下:
利用定義的類加載器加載指定的字節碼文件,如通過MyClassLoader加載C:\\Users\\Administrator\\下的Test.class字節碼文件,代碼如下所示:
(2)運行時數據區
字節碼的加載第一步,其後分別是認證、準備、解析、初始化,那麼這些步驟又具體做了哪些工作,如下圖所示:
(3)如下將介紹運行時數據區,主要分為方法區、Java堆、虛擬機棧、本地方法棧、程序計數器。其中方法區和Java堆一樣,是各個線程共享的內存區域,而虛擬機棧、本地方法棧、程序計數器是線程私有的內存區。
Java堆:Java堆是Java虛擬機所管理的內存中最大的一塊,被進程的所有線程共享,在虛擬機啟動時被創建。該區域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這裡分配內存,隨着JIT編譯器的發展與逃逸分支技術逐漸成熟,棧上分配、標量替換等優化技術使得對象在堆上的分配內存變得不是那麼“絕對”。Java堆是垃圾收集器管理的主要區域。由於現在的收集器基本都採用分代收集算法,所以Java堆中還可以分為老年代和新生代(Eden、From Survivor、To Survivor)。根據Java虛擬機規範,Java堆可以處於物理上不連續的內存空間,只要邏輯上連續即可。該區域的大小可以通過-Xmx和-Xms參數來擴展,如果堆中沒有內存完成實例分配,並且堆也無法擴展,將會拋出OutOfMemoryError異常。
方法區:用於存儲被Java虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。不同於Java堆的是,Java虛擬機規範對方法區的限制非常寬鬆,可以選擇不實現垃圾收集。但並非數據進入了方法區就“永久”存在了,這區域內存回收目標主要是針對常量池的回收和對類型的卸載。如果該區域內存不足也會拋出OutOfMemoryError異常。
常量池:這個名詞可能大家也經常見,是方法區的一部分。Class文件除了有類的版本、字段、方法、接口等描述信息外,還有一項信息就是常量池,用於存放編譯期生成的各種字面量和符號引用。Java虛擬機運行期間,也可能將新的常量放入常量池(如String類的intern()方法)。
虛擬機棧:線程私有,生命周期與線程相同。虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行時都會創建一個棧幀用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧到出棧的過程。如果請求的站深度大於虛擬機所允許的深度,將拋出StackOverflowError異常,虛擬機棧在動態擴展時如果無法申請到足夠的內存,就會拋出OutOfMemoryError異常。
過最簡單的一段代碼解釋一下,程序在運行時數據區個部分的變化情況。
(4)通過編譯器將Test.java文件編譯為Test.class,利用javap -verbose Test.class對編譯後的字節碼進行分析,如下圖所示:
(5)看看運行時數據區的變化:
java是什麼東西?
Java說白了就是一門語言,像我們平時學校里學的英語,或者其他外語一樣,是和其他人交流的工具,讓別人知道你要表達什麼,只不過Java語言是面向計算機的,人與機器交流,讓計算機懂得我們所要表達的,從而讓計算機運行出我們想要的結果。
java是什麼東西
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/186420.html