首先cd到你java文件存放的目錄,比如你的java文件的名稱為helloworld.java,在cmd中輸入javac
helloworld.java
敲擊回車,這個命令會將你的java文件編譯成class文件,然後在cmd框中輸入java
helloworld敲擊回車就能運行你的java文件輸出結果
B. 如何設置myeclipse的jvm啟動參數
-Xint
設置jvm以解釋模式運行,所有的位元組碼將被直接執行,而不會編譯成本地碼。
-Xbatch
關閉後台代碼編譯,強制在前台編譯,編譯完成之後才能進行代碼執行;
默認情況下,jvm在後台進行編譯,若沒有編譯完成,則前台運行代碼時以解釋模式運行。
-Xbootclasspath:bootclasspath
讓jvm從指定路徑(可以是分號分隔的目錄、jar、或者zip)中載入bootclass,用來替換jdk的rt.jar;若非必要,一般不會用到;
-Xbootclasspath/a:path
將指定路徑的所有文件追加到默認bootstrap路徑中;
-Xbootclasspath/p:path
讓jvm優先於bootstrap默認路徑載入指定路徑的所有文件;
-Xcheck:jni
對JNI函數進行附加check;此時jvm將校驗傳遞給JNI函數參數的合法性,在本地代碼中遇到非法數據時,jmv將報一個致命錯誤而終止;使用該參數後將造成性能下降,請慎用。
-Xfuture
讓jvm對類文件執行嚴格的格式檢查(默認jvm不進行嚴格格式檢查),以符合類文件格式規范,推薦開發人員使用該參數。
-Xnoclassgc
關閉針對class的gc功能;因為其阻止內存回收,所以可能會導致OutOfMemoryError錯誤,慎用;
-Xincgc
開啟增量gc(默認為關閉);這有助於減少長時間GC時應用程序出現的停頓;但由於可能和應用程序並發執行,所以會降低CPU對應用的處理能力。
-Xloggc:file
與-verbose:gc功能類似,只是將每次GC事件的相關情況記錄到一個文件中,文件的位置最好在本地,以避免網路的潛在問題。
若與verbose命令同時出現在命令行中,則以-Xloggc為准。
-Xmsn
指定jvm堆的初始大小,默認為物理內存的1/64,最小為1M;可以指定單位,比如k、m,若不指定,則默認為位元組。
-Xmxn
指定jvm堆的最大值,默認為物理內存的1/4或者1G,最小為2M;單位與-Xms一致。
-Xprof
跟蹤正運行的程序,並將跟蹤數據在標准輸出輸出;適合於開發環境調試。
-Xrs
減少jvm對操作系統信號(signals)的使用,該參數從1.3.1開始有效;
從jdk1.3.0開始,jvm允許程序在關閉之前還可以執行一些代碼(比如關閉資料庫的連接池),即使jvm被突然終止;
jvm 關閉工具通過監控控制台的相關事件而滿足以上的功能;更確切的說,通知在關閉工具執行之前,先注冊控制台的控制handler,然後對 CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
CTRL_SHUTDOWN_EVENT這幾類事件直接返回true。
但如果jvm以服務的形式在後台運行(比如servlet引擎),他能接 收CTRL_LOGOFF_EVENT事件,但此時並不需要初始化關閉程序;為了避免類似沖突的再次出現,從jdk1.3.1開始提供-Xrs參數;當此 參數被設置之後,jvm將不接收控制台的控制handler,也就是說他不監控和處理CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, or
CTRL_SHUTDOWN_EVENT事件。
-Xssn
設置單個線程棧的大小,一般默認為512k。
上面這些參數中,比如-Xmsn、-Xmxn……都是我們性能優化中很重要的參數;
-Xprof、-Xloggc:file等都是在沒有專業跟蹤工具情況下排錯的好手;
在上一小節中提到的關於JProfiler的配置中就使用到了-Xbootclasspath/a:path;
非Stable參數
前面我們提到用-XX作為前綴的參數列表在jvm中可能是不健壯的,SUN也不推薦使用,後續可能會在沒有通知的情況下就直接取消了;但是由於這些參數中的確有很多是對我們很有用的,比如我們經常會見到的-XX:PermSize、-XX:MaxPermSize等等;
下面我們將就Java HotSpot VM中-XX:的可配置參數列表進行描述;
這些參數可以被鬆散的聚合成三類:
行為參數(Behavioral Options):用於改變jvm的一些基礎行為;
性能調優(Performance Tuning):用於jvm的性能調優;
調試參數(Debugging
Options):一般用於打開跟蹤、列印、輸出等jvm參數,用於顯示jvm更加詳細的信息;
由於sun官方文檔中對各參數的描述也都非常少(大多隻有一句話),而且大多涉及OS層面的東西,很難描述清楚,所以以下是挑選了一些我們開發中可能會用得比較多的配置項,若需要查看所有參數列表,可以點擊HotSpot VM Specific
Options.查看原文;
首先來介紹行為參數:
參數及其默認值
描述
-XX:-DisableExplicitGC
禁止調用System.gc();但jvm的gc仍然有效
-XX:+MaxFDLimit
最大化文件描述符的數量限制
-XX:+ScavengeBeforeFullGC
新生代GC優先於Full GC執行
-XX:+UseGCOverheadLimit
在拋出OOM之前限制jvm耗費在GC上的時間比例
-XX:-UseConcMarkSweepGC
對老生代採用並發標記交換演算法進行GC
-XX:-UseParallelGC
啟用並行GC
-XX:-UseParallelOldGC
對Full GC啟用並行,當-XX:-UseParallelGC啟用時該項自動啟用
-XX:-UseSerialGC
啟用串列GC
-XX:+UseThreadPriorities
啟用本地線程優先順序
上面表格中黑體的三個參數代表著jvm中GC執行的三種方式,即串列、並行、並發;
串列(SerialGC)是jvm的默認GC方式,一般適用於小型應用和單處理器,演算法比較簡單,GC效率也較高,但可能會給應用帶來停頓;
並行(ParallelGC)是指GC運行時,對應用程序運行沒有影響,GC和app兩者的線程在並發執行,這樣可以最大限度不影響app的運行;
並發(ConcMarkSweepGC)是指多個線程並發執行GC,一般適用於多處理器系統中,可以提高GC的效率,但演算法復雜,系統消耗較大;
性能調優參數列表:
參數及其默認值
描述
-XX:LargePageSizeInBytes=4m
設置用於Java堆的大頁面尺寸
-XX:MaxHeapFreeRatio=70
GC後java堆中空閑量占的最大比例
-XX:MaxNewSize=size
新生成對象能佔用內存的最大值
-XX:MaxPermSize=64m
老生代對象能佔用內存的最大值
-XX:MinHeapFreeRatio=40
GC後java堆中空閑量占的最小比例
-XX:NewRatio=2
新生代內存容量與老生代內存容量的比例
-XX:NewSize=2.125m
新生代對象生成時佔用內存的默認值
-XX:ReservedCodeCacheSize=32m
保留代碼佔用的內存容量
-XX:ThreadStackSize=512
設置線程棧大小,若為0則使用系統默認值
-XX:+UseLargePages
使用大頁面內存
我們在日常性能調優中基本上都會用到以上黑體的這幾個屬性;
調試參數列表:
參數及其默認值
描述
-XX:-CITime
列印消耗在JIT編譯的時間
-XX:ErrorFile=./hs_err_pid.log
保存錯誤日誌或者數據到文件中
-XX:-ExtendedDTraceProbes
開啟solaris特有的dtrace探針
-XX:HeapDumpPath=./java_pid.hprof
指定導出堆信息時的路徑或文件名
-XX:-HeapDumpOnOutOfMemoryError
當首次遭遇OOM時導出此時堆中相關信息
-XX:
出現致命ERROR之後運行自定義命令
-XX:OnOutOfMemoryError=";"
當首次遭遇OOM時執行自定義命令
-XX:-PrintClassHistogram
遇到Ctrl-Break後列印類實例的柱狀信息,與jmap -histo功能相同
-XX:-PrintConcurrentLocks
遇到Ctrl-Break後列印並發鎖的相關信息,與jstack -l功能相同
-XX:-PrintCommandLineFlags
列印在命令行中出現過的標記
-XX:-PrintCompilation
當一個方法被編譯時列印相關信息
-XX:-PrintGC
每次GC時列印相關信息
-XX:-PrintGC Details
每次GC時列印詳細信息
-XX:-PrintGCTimeStamps
列印每次GC的時間戳
-XX:-TraceClassLoading
跟蹤類的載入信息
-XX:-TraceClassLoadingPreorder
跟蹤被引用到的所有類的載入信息
-XX:-TraceClassResolution
跟蹤常量池
-XX:-TraceClassUnloading
跟蹤類的卸載信息
-XX:-TraceLoaderConstraints
跟蹤類載入器約束的相關信息
C. 誰能簡單闡述下java編譯執行的過程
Java虛擬機(JVM)是可運行Java代碼的假想計算機。
只要根據JVM規格描述將解釋器移植到特定的計算機上,就能保證經過編譯的任何Java代碼能夠在該系統上運行。
本文首先簡要介紹從Java文件的編譯到最終執行的過程,隨後對JVM規格描述作一說明。
一.Java源文件的編譯、下載、解釋和執行
Java應用程序的開發周期包括編譯、下載、解釋和執行幾個部分。
Java編譯程序將Java源程序翻譯為JVM可執行代碼?位元組碼。
這一編譯過程同C/C++的編譯有些不同。
當C編譯器編譯生成一個對象的代碼時,該代碼是為在某一特定硬體平台運行而產生的。
因此,在編譯過程中,編譯程序通過查表將所有對符號的引用轉換為特定的內存偏移量,以保證程序運行。
Java編譯器卻不將對變數和方法的引用編譯為數值引用,也不確定程序執行過程中的內存布局,而是將這些符號引用信息保留在位元組碼中,由解釋器在運行過程中創立內存布局,然後再通過查表來確定一個方法所在的地址。
這樣就有效的保證了Java的可移植性和安全性。
運行JVM位元組碼的工作是由解釋器來完成的。
解釋執行過程分三部進行:代碼的裝入、代碼的校驗和代碼的執行。
裝入代碼的工作由"類裝載器"(classloader)完成。
類裝載器負責裝入運行一個程序需要的所有代碼,這也包括程序代碼中的類所繼承的類和被其調用的類。
當類裝載器裝入一個類時,該類被放在自己的名字空間中。
除了通過符號引用自己名字空間以外的類,類之間沒有其他辦法可以影響其他類。
在本台計算機上的所有類都在同一地址空間內,而所有從外部引進的類,都有一個自己獨立的名字空間。
這使得本地類通過共享相同的名字空間獲得較高的運行效率,同時又保證它們與從外部引進的類不會相互影響。
當裝入了運行程序需要的所有類後,解釋器便可確定整個可執行程序的內存布局。
解釋器為符號引用同特定的地址空間建立對應關系及查詢表。
通過在這一階段確定代碼的內存布局,Java很好地解決了由超類改變而使子類崩潰的問題,同時也防止了代碼對地址的非法訪問。
隨後,被裝入的代碼由位元組碼校驗器進行檢查。
校驗器可發現操作數棧溢出,非法數據類型轉化等多種錯誤。
通過校驗後,代碼便開始執行了。
Java位元組碼的執行有兩種方式:
1.即時編譯方式:解釋器先將位元組碼編譯成機器碼,然後再執行該機器碼。
2.解釋執行方式:解釋器通過每次解釋並執行一小段代碼來完成Java位元組碼程序的所有操作。
通常採用的是第二種方法。
由於JVM規格描述具有足夠的靈活性,這使得將位元組碼翻譯為機器代碼的工作
具有較高的效率。
對於那些對運行速度要求較高的應用程序,解釋器可將Java位元組碼即時編譯為機器碼,從而很好地保證了Java代碼的可移植性和高性能。
二.JVM規格描述
JVM的設計目標是提供一個基於抽象規格描述的計算機模型,為解釋程序開發人員提很好的靈活性,同時也確保Java代碼可在符合該規范的任何系統上運行。
JVM對其實現的某些方面給出了具體的定義,特別是對Java可執行代碼,即位元組碼(Bytecode)的格式給出了明確的規格。
這一規格包括操作碼和操作數的語法和數值、標識符的數值表示方式、以及Java類文件中的Java對象、常量緩沖池在JVM的存儲映象。
這些定義為JVM解釋器開發人員提供了所需的信息和開發環境。
Java的設計者希望給開發人員以隨心所欲使用Java的自由。
JVM定義了控制Java代碼解釋執行和具體實現的五種規格,它們是:
JVM指令系統
JVM寄存器
JVM棧結構
JVM碎片回收堆
JVM存儲區
2.1JVM指令系統
JVM指令系統同其他計算機的指令系統極其相似。
Java指令也是由操作碼和操作數兩部分組成。
操作碼為8位二進制數,操作數進緊隨在操作碼的後面,其長度根據需要而不同。
操作碼用於指定一條指令操作的性質(在這里我們採用匯編符號的形式進行說明),如iload表示從存儲器中裝入一個整數,anewarray表示為一個新數組分配空間,iand表示兩個整數的"與",ret用於流程式控制制,表示從對某一方法的調用中返回。
當長度大於8位時,操作數被分為兩個以上位元組存放。
JVM採用了"bigendian"的編碼方式來處理這種情況,即高位bits存放在低位元組中。
這同Motorola及其他的RISCCPU採用的編碼方式是一致的,而與Intel採用的"littleendian"的編碼方式即低位bits存放在低位位元組的方法不同。
Java指令系統是以Java語言的實現為目的設計的,其中包含了用於調用方法和監視多先程系統的指令。
Java的8位操作碼的長度使得JVM最多有256種指令,目前已使用了160多種操作碼。
2.2JVM指令系統
所有的CPU均包含用於保存系統狀態和處理器所需信息的寄存器組。
如果虛擬機定義較多的寄存器,便可以從中得到更多的信息而不必對棧或內存進行訪問,這有利於提高運行速度。
然而,如果虛擬機中的寄存器比實際CPU的寄存器多,在實現虛擬機時就會佔用處理器大量的時間來用常規存儲器模擬寄存器,這反而會降低虛擬機的效率。
針對這種情況,JVM只設置了4個最為常用的寄存器。
它們是:
pc程序計數器
optop操作數棧頂指針
frame當前執行環境指針
vars指向當前執行環境中第一個局部變數的指針
所有寄存器均為32位。
pc用於記錄程序的執行。
optop,frame和vars用於記錄指向Java棧區的指針。
2.3JVM棧結構
作為基於棧結構的計算機,Java棧是JVM存儲信息的主要方法。
當JVM得到一個Java位元組碼應用程序後,便為該代碼中一個類的每一個方法創建一個棧框架,以保存該方法的狀態信息。
每個棧框架包括以下三類信息:
局部變數
執行環境
操作數棧
局部變數用於存儲一個類的方法中所用到的局部變數。
vars寄存器指向該變數表中的第一個局部變數。
執行環境用於保存解釋器對Java位元組碼進行解釋過程中所需的信息。
它們是:上次調用的方法、局部變數指針和操作數棧的棧頂和棧底指針。
執行環境是一個執行一個方法的控制中心。
例如:如果解釋器要執行iadd(整數加法),首先要從frame寄存器中找到當前執行環境,而後便從執行環境中找到操作數棧,從棧頂彈出兩個整數進行加法運算,最後將結果壓入棧頂。
操作數棧用於存儲運算所需操作數及運算的結果。
2.4JVM碎片回收堆
Java類的實例所需的存儲空間是在堆上分配的。
解釋器具體承擔為類實例分配空間的工作。
解釋器在為一個實例分配完存儲空間後,便開始記錄對該實例所佔用的內存區域的使用。
一旦對象使用完畢,便將其回收到堆中。
在Java語言中,除了new語句外沒有其他方法為一對象申請和釋放內存。
對內存進行釋放和回收的工作是由Java運行系統承擔的。
這允許Java運行系統的設計者自己決定碎片回收的方法。
在SUN公司開發的Java解釋器和HotJava環境中,碎片回收用後台線程的方式來執行。
這不但為運行系統提供了良好的性能,而且使程序設計人員擺脫了自己控制內存使用的風險。
2.5JVM存儲區
JVM有兩類存儲區:常量緩沖池和方法區。
常量緩沖池用於存儲類名稱、方法和欄位名稱以及串常量。
方法區則用於存儲Java方法的位元組碼。
對於這兩種存儲區域具體實現方式在JVM規格中沒有明確規定。
這使得Java應用程序的存儲布局必須在運行過程中確定,依賴於具體平台的實現方式。
JVM是為Java位元組碼定義的一種獨立於具體平台的規格描述,是Java平 *** 立性的基礎。
目前的JVM還存在一些限制和不足,有待於進一步的完善,但無論如何,JVM的思想是成功的。
對比分析:如果把Java原程序想像成我們的C++原程序,Java原程序編譯後生成的位元組碼就相當於C++原程序編譯後的80x86的機器碼(二進製程序文件),JVM虛擬機相當於80x86計算機系統,Java解釋器相當於80x86CPU。
在80x86CPU上運行的是機器碼,在Java解釋器上運行的是Java位元組碼。
Java解釋器相當於運行Java位元組碼的「CPU」,但該「CPU」不是通過硬體實現的,而是用軟體實現的。
Java解釋器實際上就是特定的平台下的一個應用程序。
只要實現了特定平台下的解釋器程序,Java位元組碼就能通過解釋器程序在該平台下運行,這是Java跨平台的根本。
當前,並不是在所有的平台下都有相應Java解釋器程序,這也是Java並不能在所有的平台下都能運行的原因,它只能在已實現了Java解釋器程序的平台下運行。
D. JVM原理是什麼
JVM工作原理和特點主要是指操作系統裝入JVM是通過jdk中Java.exe來完成,通過下面4步來完成JVM環境.
1.創建JVM裝載環境和配置
2.裝載JVM.dll
3.初始化JVM.dll並掛界到JNIENV(JNI調用介面)實例
4.調用JNIEnv實例裝載並處理class類。
E. java為什麼要編譯
因為java的跨平台特性,java所謂的一次編譯,到處運行,關鍵就是在於java的虛擬機,也就是jvm,jvm只認識位元組碼,所以你寫好的java代碼就需要編譯成位元組碼才能在jvm上運行。其實不只是java需要編譯,C也需要編譯,機器本身並不能認識你寫的代碼,它們只認識0、1這樣的位元組碼,所以無論是你用什麼樣的語言編寫的代碼,要想最終在物理機器上運行,都要進行編譯。
F. java編譯器和JVM有什麼區別
java編譯器把java源碼編譯成位元組碼 (.class文件).
jvm是在運行期將class文件編譯成機器碼文件.供程序運行.