㈠ 如何設置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
跟蹤類載入器約束的相關信息
㈡ java中將java源文件編譯成位元組碼文件這個過程是由JVM執行的嗎
不是,JVM只是執行編譯以後的位元組碼,編譯是由javac(java編譯器)執行的。
㈢ jdk中兩個重要可執行程序分別是什麼
JDK是SUN公司提供的一套Java開發環境,
其中包含Java編譯器、Java運行工具、Java文檔生成工具、以及Java打包工具。
在JDK的bin目錄下存放了很多可執行文件,其中最重要的就是java.exe和javac.exe、舉例說明:
_正常我們編寫好程序存放在源文件a.java中,之後會通過javac.exe(Java編譯器工具)進行編譯,編譯完成後會生成a.class文件(位元組碼文件,是可執行的java程序),
_然後接下來java.exe(Java運行工具)會啟動JVM(Java虛擬機)進程,Java虛擬機相當於一個小型的操作系統,它專門負責運行由Java編譯器生成的位元組碼文件(a.class),從而使程序運行。
㈣ 簡述jvm工作原理
Java是一種技術,它由四方面組成:Java編程語言、Java類文件格式、Java虛擬機和Java應用程序介面(Java API)。
運行期環境代表著Java平台,開發人員編寫Java代碼(.java文件),然後將之編譯成位元組碼(.class文件),再然後位元組碼被裝入內存,一旦位元組碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。
Java平台由Java虛擬機和Java應用程序介面搭建,Java語言則是進入這個平台的通道,用Java語言編寫並編譯的程序可以運行在這個平台上。
在Java平台的結構中, 可以看出,Java虛擬機(JVM) 處在核心的位置,是程序與底層操作系統和硬體無關的關鍵。它的下方是移植介面,移植介面由兩部分組成:適配器和Java操作系統, 其中依賴於平台的部分稱為適配器;JVM 通過移植介面在具體的平台和操作系統上實現;在JVM 的上方是Java的基本類庫和擴展類庫以及它們的API, 利用Java API編寫的應用程序(application) 和小程序(Java applet) 可以在任何Java平台上運行而無需考慮底層平台, 就是因為有Java虛擬機(JVM)實現了程序與操作系統的分離,從而實現了Java 的平台無關性。
JVM在它的生存周期中有一個明確的任務,那就是運行Java程序,因此當Java程序啟動的時候,就產生JVM的一個實例;當程序運行結束的時候,該實例也跟著消失了。下面我們從JVM的體系結構和它的運行過程這兩個方面來對它進行比較深入的研究。
1、Java虛擬機的體系結構
·每個JVM都有兩種機制:
①類裝載子系統:裝載具有適合名稱的類或介面
②執行引擎:負責執行包含在已裝載的類或介面中的指令
·每個JVM都包含:
方法區、Java堆、Java棧、本地方法棧、指令計數器及其他隱含寄存器
2、Java代碼編譯和執行的整個過程
也正如前面所說,Java代碼的編譯和執行的整個過程大概是:開發人員編寫Java代碼(.java文件),然後將之編譯成位元組碼(.class文件),再然後位元組碼被裝入內存,一旦位元組碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。
(1)Java代碼編譯是由Java源碼編譯器來完成,也就是Java代碼到JVM位元組碼(.class文件)的過程。
2)Java位元組碼的執行是由JVM執行引擎來完成
Java代碼編譯和執行的整個過程包含了以下三個重要的機制:
·Java源碼編譯機制
·類載入機制
·類執行機制
(1)Java源碼編譯機制
Java 源碼編譯由以下三個過程組成:
①分析和輸入到符號表
②註解處理
③語義分析和生成class文件
最後生成的class文件由以下部分組成:
①結構信息:包括class文件格式版本號及各部分的數量與大小的信息
②元數據:對應於Java源碼中聲明與常量的信息。包含類/繼承的超類/實現的介面的聲明信息、域與方法聲明信息和常量池
③方法信息:對應Java源碼中語句和表達式對應的信息。包含位元組碼、異常處理器表、求值棧與局部變數區大小、求值棧的類型記錄、調試符號信息
(2)類載入機制 JVM的類載入是通過ClassLoader及其子類來完成的
㈤ Java編譯成位元組碼的階段有用到JVM嗎
應該是不需要jvm的,其實javac :即java compile ,是指java編譯,java 運行文件,其實java命令就是調用的 jvm平台,交流一下吧,這是我一直以來的看法。
㈥ 運行一個項目的時候,jvm是一下把項目代碼載入進jvm,還是運行到什麼功能,在載入相應的代碼
class文件是按需載入,發生以下情況,而當前運行環境中尚未載入對應的類時,JVM才會從文件系統中載入class文件到內存中:
一、遇到new、getstatic、putstatic、invokestatic這四條指令碼時。
1、new關鍵字實例化一個類的時候。
2、讀取或設置一個的類的靜態欄位的時候。限只在本類里定義的,繼承父類的靜態欄位不算。靜態常量不算。
3、調用一個類的靜態方法時。
二、java.lang.reflect包的方法對類反射調用的時候。
三、初始化子類,父類沒有初始化的時候初始化父類。
四、虛擬機啟動時指定的主類會先被初始化。
㈦ 當使用 Java 命令運行 .class 文件的時候,就相當於啟動了一個 JVM 進程,如何理解
進程是操作系統資源管理的基本單位,運行.class文件和打開一個應用軟體(當然有些軟體可能對於多個進程)是類似的,都會創建一個操作系統進程。
你提到的"運行.class啟動的JVM進程",實際上這個就是操作系統創建的進程;這個進程需要一定的資源(CPU、內存、磁碟等)來完成一定的事情,進程之間不會相互干擾,所以每個軟體都需要操作系統分配進程。
至於你說的"JVM中有哪些進程",我理解應該是"JVM中有哪些"線程;建議去了解一下進程和線程之間的區別。我個人理解進程和線程的核心區別是:進程是資源管理、分配的基本單位,這個類比於公司;而線程是操作系統調度的基本單位,類比於公司員工。上級部門在分配資源的時候肯定是分配名額到企業,但是分配資源具體怎麼使用,則需要由企業的員工來完成。
一般JVM中的線程由用戶創建,但是JVM也會默認創建一些線程,比如垃圾回收線程。
㈧ Java創建對象是在編譯時還是在運行時
運行期。編譯好的java程序(即.class文件)需要運行在JVM中。程序,無論代碼還是數據,都需要存儲在內存中。JVM為java程序提供並管理所需要的內存空間。JVM內存分為"堆"、"棧"、"方法區"三個區域,分別用於存儲不同數據。首先JVM會檢查創建這個對象的類是否是一個以前從沒有見過的類型,如果不是,JVM將為其分配內存,如果是,java虛擬機將調用具體的ClassLoader找到對應的.class文件,並將這個文件的內容讀到內存中去。
1)堆:
1.1)用於存儲所有new出來的對象(包括成員變數)。
1.2)垃圾:沒有任何引用所指向的對象。
垃圾回收器(GC)不定時到內存中清掃垃圾,
並不一定一發現垃圾就立刻回收,
回收過程是透明的(看不到的),
通過調用System.gc()可以建議虛擬機盡快調度GC來回收。
1.3)內存泄漏:不再使用的內存沒有被及時的回收。
建議:不再使用的對象,及時將引用設置為null。
1.4)成員變數的生命周期:
創建對象時存儲在堆中,對象被回收時一並被回收。
2)棧:
2.1)用於存儲正在調用的方法中的所有局部變數(包括參數)
2.2)JVM會為每一個正在調用的方法分配一塊對應的棧幀,
棧幀中存儲方法中的局部變數(包括參數),
方法調用結束時,棧幀被清除,局部變數一並被清除。
2.3)局部變數的生命周期:
調用方法時存在棧中,方法結束時與棧幀一並被清除。
3)方法區:
3.1)用於存儲.class位元組碼文件(包括方法)。
3.2)方法只有一份,通過this來區分具體的對象。
既然對象在堆中創建,因此Java創建對象是在運行時,而不是編譯時。
㈨ 說說java文件編譯時都做了哪些事情
java有反射機制,執行編譯時會嘗試找到JRE安裝所在目錄,然後找到jvm.dll,接著啟動JVM進行初始化動作,產生3個類載入器,用來將所用到的類文件載入到內存中,會自動導入java.lang下的類文件和你想導入的類文件,查看你的代碼中是否有未處理的可控式異常,JVM會查看你寫的代碼是否符合語法,.JVM會將你所寫的java文件編譯為與系統平台無關的位元組碼文件。
㈩ Java編譯運行過程
程序員所編寫的是以.java為後綴的文件,此文件操作系統不能正確識別,因此,首先要經過編譯,生成所謂的位元組碼文件(.class),而位元組碼文件需要JVM來提供運行環境的支持。
JVM是一個軟體,安裝在操作系統中,是建立在操作系統之上的,為位元組碼文件提供運行環境,效果如圖 – 1 所示。
圖- 1
Java官方提供了針對不同平台的JVM軟體,即:不同平台的JVM是不同的。但這些JVM遵循著相同的標准,即:只要是標準的.class文件,就可以在不同的JVM上運行,而且運行的效果相同。這樣,就實現了所謂的「一次編程到處使用」。效果如圖– 2所示:
圖- 2
Java程序遵循著先編譯、後執行的原則。首先,通過javac命令將JAVA源程序(.java文件)編譯為JAVA位元組碼(.class文件),而後,通過java命令啟動JVM,由JVM來載入.class文件並運行.class文件。效果如圖 – 3所示:
圖- 3