您好,登錄后才能下訂單哦!
第一類內(nèi)存溢出,也是大家認為最多,第一反應(yīng)認為是的內(nèi)存溢出,就是堆棧溢出:
那什么樣的情況就是堆棧溢出呢?當你看到下面的關(guān)鍵字的時候它就是堆棧溢出了:
java.lang.OutOfMemoryError: ......java heap space.....
也就是當你看到heap相關(guān)的時候就肯定是堆棧溢出了,此時如果代碼沒有問題的情況下,適當調(diào)整-Xmx和-Xms是可以避免的,不過一定是代碼沒有問題的前提,為什么會溢出呢,要么代碼有問題,要么訪問量太多并且每個訪問的時間太長或者數(shù)據(jù)太多,導(dǎo)致數(shù)據(jù)釋放不掉,因為垃圾回收器是要找到那些是垃圾才能回收,這里它不會認為這些東西是垃圾,自然不會去回收了;主意這個溢出之前,可能系統(tǒng)會提前先報錯關(guān)鍵字為:
java.lang.OutOfMemoryError:GC over head limit exceeded
這種情況是當系統(tǒng)處于高頻的GC狀態(tài),而且回收的效果依然不佳的情況,就會開始報這個錯誤,這種情況一般是產(chǎn)生了很多不可以被釋放的對象,有可能是引用使用不當導(dǎo)致,或申請大對象導(dǎo)致,但是java heap space的內(nèi)存溢出有可能提前不會報這個錯誤,也就是可能內(nèi)存就直接不夠?qū)е?,而不是高頻GC.
第二類內(nèi)存溢出,PermGen的溢出,或者PermGen 滿了的提示,你會看到這樣的關(guān)鍵字:
關(guān)鍵信息為:
java.lang.OutOfMemoryError: PermGen space
原因:系統(tǒng)的代碼非常多或引用的第三方包非常多、或代碼中使用了大量的常量、或通過intern注入常量、或者通過動態(tài)代碼加載等方法,導(dǎo)致常量池的膨脹,雖然JDK 1.5以后可以通過設(shè)置對永久帶進行回收,但是我們希望的是這個地方是不做GC的,它夠用就行,所以一般情況下今年少做類似的操作,所以在面對這種情況常用的手段是:增加-XX:PermSize和-XX:MaxPermSize的大小。
第三類內(nèi)存溢出:在使用ByteBuffer中的allocateDirect()的時候會用到,很多javaNIO的框架中被封裝為其他的方法
溢出關(guān)鍵字:
java.lang.OutOfMemoryError: Direct buffer memory
如果你在直接或間接使用了ByteBuffer中的allocateDirect方法的時候,而不做clear的時候就會出現(xiàn)類似的問題,常規(guī)的引用程序IO輸出存在一個內(nèi)核態(tài)與用戶態(tài)的轉(zhuǎn)換過程,也就是對應(yīng)直接內(nèi)存與非直接內(nèi)存,如果常規(guī)的應(yīng)用程序你要將一個文件的內(nèi)容輸出到客戶端需要通過OS的直接內(nèi)存轉(zhuǎn)換拷貝到程序的非直接內(nèi)存(也就是heap中),然后再輸出到直接內(nèi)存由操作系統(tǒng)發(fā)送出去,而直接內(nèi)存就是由OS和應(yīng)用程序共同管理的,而非直接內(nèi)存可以直接由應(yīng)用程序自己控制的內(nèi)存,jvm垃圾回收不會回收掉直接內(nèi)存這部分的內(nèi)存,所以要注意了哦。
如果經(jīng)常有類似的操作,可以考慮設(shè)置參數(shù):-XX:MaxDirectMemorySize
第四類內(nèi)存溢出錯誤:
溢出關(guān)鍵字:
java.lang.StackOverflowError
這個參數(shù)直接說明一個內(nèi)容,就是-Xss太小了,我們申請很多局部調(diào)用的棧針等內(nèi)容是存放在用戶當前所持有的線程中的,線程在jdk 1.4以前默認是256K,1.5以后是1M,如果報這個錯,只能說明-Xss設(shè)置得太小,當然有些廠商的JVM不是這個參數(shù),本文僅僅針對Hotspot VM而已;不過在有必要的情況下可以對系統(tǒng)做一些優(yōu)化,使得-Xss的值是可用的。
第五類內(nèi)存溢出錯誤:
溢出關(guān)鍵字:
java.lang.OutOfMemoryError: unable to create new native thread
上面第四種溢出錯誤,已經(jīng)說明了線程的內(nèi)存空間,其實線程基本只占用heap以外的內(nèi)存區(qū)域,也就是這個錯誤說明除了heap以外的區(qū)域,無法為線程分配一塊內(nèi)存區(qū)域了,這個要么是內(nèi)存本身就不夠,要么heap的空間設(shè)置得太大了,導(dǎo)致了剩余的內(nèi)存已經(jīng)不多了,而由于線程本身要占用內(nèi)存,所以就不夠用了,說明了原因,如何去修改,不用我多說,你懂的。
第六類內(nèi)存溢出:
溢出關(guān)鍵字
java.lang.OutOfMemoryError: request {} byte for {}out of swap
這類錯誤一般是由于地址空間不夠而導(dǎo)致。
六大類常見溢出已經(jīng)說明JVM中99%的溢出情況,要逃出這些溢出情況非常困難,除非一些很怪異的故障問題會發(fā)生,比如由于物理內(nèi)存的硬件問題,導(dǎo)致了code cache的錯誤(在由byte code轉(zhuǎn)換為native code的過程中出現(xiàn),但是概率極低),這種情況內(nèi)存 會被直接crash掉,類似還有swap的頻繁交互在部分系統(tǒng)中會導(dǎo)致系統(tǒng)直接被crash掉,OS地址空間不夠的話,系統(tǒng)根本無法啟動,呵呵;JNI的濫用也會導(dǎo)致一些本地內(nèi)存無法釋放的問題,所以盡量避開JNI;socket連接數(shù)據(jù)打開過多的socket也會報類似:IOException: Too many open files等錯誤信息。
JNI就不用多說了,盡量少用,除非你的代碼太牛B了,我無話可說,呵呵,這種內(nèi)存如果沒有在被調(diào)用的語言內(nèi)部將內(nèi)存釋放掉(如C語言),那么在進程結(jié)束前這些內(nèi)存永遠釋放不掉,解決辦法只有一個就是將進程kill掉。
另外GC本身是需要內(nèi)存空間的,因為在運算和中間數(shù)據(jù)轉(zhuǎn)換過程中都需要有內(nèi)存,所以你要保證GC的時候有足夠的內(nèi)存哦,如果沒有的話GC的過程將會非常的緩慢。
順便這里就提及一些新的CMS GC的內(nèi)容和策略(有點亂,每次寫都很亂,但是能看多少看多少吧):
首先我再寫一次一前博客中的已經(jīng)寫過的內(nèi)容,就是很多參數(shù)沒啥建議值,建議值是自己在現(xiàn)場根據(jù)實際情況科學計算和測試得到的綜合效果,建議值沒有絕對好的,而且默認值很多也是有問題的,因為不同的版本和廠商都有很大的區(qū)別,默認值沒有永久都是一樣的,就像-Xss參數(shù)的變化一樣,要看到你當前的java程序heap的大致情況可以這樣看看(以下參數(shù)是隨便設(shè)置的,并不是什么默認值):
$sudo jmap -heap `pgrep java`
Attaching to process ID 4280, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 19.1-b02
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 134217728 (128.0MB)
MaxNewSize = 134217728 (128.0MB)
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 134217728 (128.0MB)
MaxPermSize = 268435456 (256.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 85721088 (81.75MB)
used = 22481312 (21.439849853515625MB)
free = 63239776 (60.310150146484375MB)
26.22611602876529% used
From Space:
capacity = 24051712 (22.9375MB)
used = 478488 (0.45632171630859375MB)
free = 23573224 (22.481178283691406MB)
1.9894134770946867% used
To Space:
capacity = 24248320 (23.125MB)
used = 0 (0.0MB)
free = 24248320 (23.125MB)
0.0% used
PS Old Generation
capacity = 939524096 (896.0MB)
used = 16343864 (15.586723327636719MB)
free = 923180232 (880.4132766723633MB)
1.7395896571023124% used
PS Perm Generation
capacity = 134217728 (128.0MB)
used = 48021344 (45.796722412109375MB)
free = 86196384 (82.20327758789062MB)
35.77868938446045% used
付:sudo是需要拿到管理員權(quán)限,如果你的系統(tǒng)權(quán)限很大那么就不需要了,最后的grep java那個內(nèi)容如果不對,可以直接通過jps或者ps命令將和java相關(guān)的進程號直接寫進去,如:java -map 4280,這個參數(shù)其實完全可以通過jstat工具來替代,而且看到的效果更加好,這個參數(shù)在線上應(yīng)用中,盡量少用(尤其是高并發(fā)的應(yīng)用中),可能會觸發(fā)JVM的bug,導(dǎo)致應(yīng)用掛起;在jvm 1.6u14后可以編寫任意一段程序,然后在運行程序的時候,增加參數(shù)為:-XX:+PrintFlagsFinal來輸出當前JVM中運行時的參數(shù)值,或者通過jinfo來查看,jinfo是非常強大的工具,可以對部分參數(shù)進行動態(tài)修改,當然內(nèi)存相關(guān)的東西是不能修改的,只能增加一些不是很相關(guān)的參數(shù),有關(guān)JVM的工具使用,后續(xù)文章中如果有機會我們再來探討,不是本文的重點;補充:關(guān)于參數(shù)的默認值對不同的JVM版本、不同的廠商、運行于不同的環(huán)境(一般和位數(shù)有關(guān)系)默認值會有區(qū)別。
OK,再說下反復(fù)的一句,沒有必要的話就不要亂設(shè)置參數(shù),參數(shù)不是拿來玩的,默認的參數(shù)對于這門JDK都是有好處的,關(guān)鍵是否適合你的應(yīng)用場景,一般來講你常規(guī)的只需要設(shè)置以下幾個參數(shù)就可以了:
-server 表示為服務(wù)器端,會提供很多服務(wù)器端默認的配置,如并行回收,而服務(wù)器上一般這個參數(shù)都是默認的,所以都是可以省掉,與之對應(yīng)的還有一個-client參數(shù),一般在64位機器上,JVM是默認啟動-server參數(shù),也就是默認啟動并行GC的,但是是ParallelGC而不是ParallelOldGC,兩者算法不同(后面會簡單說明下),而比較特殊的是windows 32位上默認是-client,這兩個的區(qū)別不僅僅是默認的參數(shù)不一樣,在jdk包下的jre包下一般會包含client和server包,下面分別對應(yīng)啟動的動態(tài)鏈接庫,而真正看到的java、javac等相關(guān)命令指示一個啟動導(dǎo)向,它只是根據(jù)命令找到對應(yīng)的JVM并傳入jvm中進行啟動,也就是看到的java.exe這些文件并不是jvm;說了這么多,最終總結(jié)一下就是,-server和-client就是完全不同的兩套VM,一個用于桌面應(yīng)用,一個用于服務(wù)器的。
-Xmx 為Heap區(qū)域的最大值
-Xms 為Heap區(qū)域的初始值,線上環(huán)境需要與-Xmx設(shè)置為一致,否則capacity的值會來回飄動,飄得你心曠神怡,你懂的。
-Xss(或-ss) 這個其實也是可以默認的,如果你真的覺得有設(shè)置的必要,你就改下吧,1.5以后是1M的默認大小(指一個線程的native空間),如果代碼不多,可以設(shè)置小點來讓系統(tǒng)可以接受更大的內(nèi)存。注意,還有一個參數(shù)是-XX:ThreadStackSize,這兩個參數(shù)在設(shè)置的過程中如果都設(shè)置是有沖突的,一般按照JVM常理來說,誰設(shè)置在后面,就以誰為主,但是最后發(fā)現(xiàn)如果是在1.6以上的版本,-Xss設(shè)置在后面的確都是以-Xss為主,但是要是-XX:ThreadStackSize設(shè)置在后面,主線程還是為-Xss為主,而其它線程以-XX:ThreadStackSize為主,主線程做了一個特殊判定處理;單獨設(shè)置都是以本身為主,-Xss不設(shè)置也不會采用其默認值,除非兩個都不設(shè)置會采用-Xss的默認值。另外這個參數(shù)針對于hotspot的vm,在IBM的jvm中,還有一個參數(shù)為-Xoss,主要原因是IBM在對棧的處理上有操作數(shù)棧和方法棧等各種不同的棧種類,而hotspot不管是什么棧都放在一個私有的線程內(nèi)部的,不區(qū)分是什么棧,所以只需要設(shè)置一個參數(shù),而IBM的J9不是這樣的;有關(guān)棧上的細節(jié),后續(xù)我們有機會專門寫文章來說明。
-XX:PermSize與-XX:MaxPermSize兩個包含了class的裝載的位置,或者說是方法區(qū)(但不是本地方法區(qū)),在Hotspot默認情況下為64M,主意全世界的JVM只有hostpot的VM才有Perm的區(qū)域,或者說只有hotspot才有對用戶可以設(shè)置的這塊區(qū)域,其他的JVM都沒有,其實并不是沒有這塊區(qū)域,而是這塊區(qū)域沒有讓用戶來設(shè)置,其實這塊區(qū)域本身也不應(yīng)該讓用戶來設(shè)置,我們也沒有一個明確的說法這塊空間必須要設(shè)置多大,都是拍腦袋設(shè)置一個數(shù)字,如果發(fā)布到線上看下如果用得比較多,就再多點,如果用的少,就減少點,而這塊區(qū)域和性能關(guān)鍵沒有多大關(guān)系,只要能裝下就OK,并且時不時會因為Perm不夠而導(dǎo)致Full GC,所以交給開發(fā)者來調(diào)節(jié)這個參數(shù)不知道是怎么想的;所以O(shè)racle將在新一代JVM中將這個區(qū)域徹底刪掉,也就是對用戶透明,G1的如果真正穩(wěn)定起來,以后JVM的啟動參數(shù)將會非常簡單,而且理論上管理再大的內(nèi)存也是沒有問題的,其實G1(garbage first,一種基于region的垃圾收集回收器)已經(jīng)在hotspot中開始有所試用,不過目前效果不好,還不如CMS呢,所以只是試用,G1已經(jīng)作為ORACLE對JVM研發(fā)的最高重點,CMS自現(xiàn)在最高版本后也不再有新功能(可以修改bug),該項目已經(jīng)進行5年,尚未發(fā)布正式版,CMS是四五年前發(fā)布的正式版,但是是最近一兩年才開始穩(wěn)定,而G1的復(fù)雜性將會遠遠超越CMS,所以要真正使用上G1還有待考察,全世界目前只有IBM J9真正實現(xiàn)了G1論文中提到的思想(論文于05年左右發(fā)表),IBM已經(jīng)將J9應(yīng)用于websphere中,但是并不代表這是全世界最好的jvm,全世界最好的jvm是Azul(無停頓垃圾回收算法和一個零開銷的診斷/監(jiān)控工具),幾乎可以說這個jvm是沒有暫停的,在全世界很多頂尖級的公司使用,不過價格非常貴,不能直接使用,目前這個jvm的主導(dǎo)者在研究JRockit,而目前hotspot和JRockit都是Oracle的,所以他們可能會合并,所以我們應(yīng)該對JVM的性能充滿信心。
也就是說你常用的情況下只需要設(shè)置4個參數(shù)就OK了,除非你的應(yīng)用有些特殊,否則不要亂改,那么來看看一些其他情況的參數(shù)吧:
先來看個不大常用的,就是大家都知道JVM新的對象應(yīng)該說幾乎百分百的在Eden里面,除非Eden真的裝不下,我們不考慮這種變態(tài)的問題,因為線上環(huán)境Eden區(qū)域都是不小的,來降低GC的次數(shù)以及全局 GC的概率;而JVM習慣將內(nèi)存按照較為連續(xù)的位置進行分配,這樣使得有足夠的內(nèi)存可以被分配,減少碎片,那么對于內(nèi)存最后一個位置必然就有大量的征用問題,JVM在高一點的版本里面提出了為每個線程分配一些私有的區(qū)域來做來解決這個問題,而1.5后的版本還可以動態(tài)管理這些區(qū)域,那么如何自己設(shè)置和查看這些區(qū)域呢,看下英文全稱為:Thread Local Allocation Buffer,簡稱就是:TLAB,即內(nèi)存本地的持有的buffer,設(shè)置參數(shù)有:
-XX:+UseTLAB 啟用這種機制的意思
-XX:TLABSize=<size in kb> 設(shè)置大小,也就是本地線程中的私有區(qū)域大?。ㄖ挥羞@個區(qū)域放不下才會到Eden中去申請)。
-XX:+ResizeTLAB 是否啟動動態(tài)修改
這幾個參數(shù)在多CPU下非常有用。
-XX:+PrintTLAB 可以輸出TLAB的內(nèi)容。
下面再閑扯些其它的參數(shù):
如果你需要對Yong區(qū)域進行并行回收應(yīng)該如何修改呢?在jdk1.5以后可以使用參數(shù):
-XX:+UseParNewGC
注意: 與它沖突的參數(shù)是:-XX:+UseParallelOldGC和-XX:+UseSerialGC,如果需要用這個參數(shù),又想讓整個區(qū)域是并行回收的,那么就使用-XX:+UseConcMarkSweepGC參數(shù)來配合,其實這個參數(shù)在使用了CMS后,默認就會啟動該參數(shù),也就是這個參數(shù)在CMS GC下是無需設(shè)置的,后面會提及到這些參數(shù)。
默認服務(wù)器上的對Full并行GC策略為(這個時候Yong空間回收的時候啟動PSYong算法,也是并行回收的):
-XX:+UseParallelGC
另外,在jdk1.5后出現(xiàn)一個新的參數(shù)如下,這個對Yong的回收算法和上面一樣,對Old區(qū)域會有所區(qū)別,上面對Old回收的過程中會做一個全局的Compact,也就是全局的壓縮操作,而下面的算法是局部壓縮,為什么要局部壓縮呢?是因為JVM發(fā)現(xiàn)每次壓縮后再邏輯上數(shù)據(jù)都在Old區(qū)域的左邊位置,申請的時候從左向右申請,那么生命力越長的對象就一般是靠左的,所以它認為左邊的對象就是生命力很強,而且較為密集的,所以它針對這種情況進行部分密集,但是這兩種算法mark階段都是會暫停的,而且存活的對象越多活著的越多;而ParallelOldGC會進行部分壓縮算法(主意一點,最原始的copy算法是不需要經(jīng)過mark階段,因為只需要找到一個或活著的就只需要做拷貝就可以,而Yong區(qū)域借用了Copy算法,只是唯一的區(qū)別就是傳統(tǒng)的copy算法是采用兩個相同大小的內(nèi)存來拷貝,浪費空間為50%,所以分代的目標就是想要實現(xiàn)很多優(yōu)勢所在,認為新生代85%以上的對象都應(yīng)該是死掉的,所以S0和S1一般并不是很大),該算法為jdk 1.5以后對于絕大部分應(yīng)用的最佳選擇。
-XX:+UseParallelOldGC
-XX:ParallelGCThread=12:并行回收的線程數(shù),最好根據(jù)實際情況而定,因為線程多往往存在征用調(diào)度和上下文切換的開銷;而且也并非CPU越多線程數(shù)也可以設(shè)置越大,一般設(shè)置為12就再增加用處也不大,主要是算法本身內(nèi)部的征用會導(dǎo)致其線程的極限就是這樣。
設(shè)置Yong區(qū)域大?。?/span>
-Xmn Yong區(qū)域的初始值和最大值一樣大
-XX:NewSize和-XX:MaxNewSize如果設(shè)置以為一樣大就是和-Xmn,在JRockit中會動態(tài)變化這些參數(shù),根據(jù)實際情況有可能會變化出兩個Yong區(qū)域,或者沒有Yong區(qū)域,有些時候會生出來一個半長命對象區(qū)域;這里除了這幾個參數(shù)外,還有一個參數(shù)是NewRatio是設(shè)置Old/Yong的倍數(shù)的,這幾個參數(shù)都是有沖突的,服務(wù)器端建議是設(shè)置-Xmn就可以了,如果幾個參數(shù)全部都有設(shè)置,-Xmn和-XX:NewSize與-XX:MaxNewSize將是誰設(shè)置在后面,以誰的為準,而-XX:NewSize -XX:MaxNewSize與-XX:NewRatio時,那么參數(shù)設(shè)置的結(jié)果可能會以下這樣的(jdk 1.4.1后):
min(MaxNewSize,max(NewSize, heap/(NewRatio+1)))
-XX:NewRatio為Old區(qū)域為Yong的多少倍,間接設(shè)置Yong的大小,1.6中如果使用此參數(shù),則默認會在適當時候被動態(tài)調(diào)整,具體請看下面參數(shù)UseAdaptiveSizepollcy 的說明。
三個參數(shù)不要同時設(shè)置,因為都是設(shè)置Yong的大小的。
-XX:SurvivorRatio:該參數(shù)為Eden與兩個求助空間之一的比例,注意Yong的大小等價于Eden + S0 + S1,S0和S1的大小是等價的,這個參數(shù)為Eden與其中一個S區(qū)域的大小比例,如參數(shù)為8,那么Eden就占用Yong的80%,而S0和S1分別占用10%。
以前的老版本有一個參數(shù)為:-XX:InitialSurivivorRatio,如果不做任何設(shè)置,就會以這個參數(shù)為準,這個參數(shù)的默認值就是8,不過這個參數(shù)并不是Eden/Survivor的大小,而是Yong/Survivor,所以所以默認值8,代表每一個S區(qū)域的空間大小為Yong區(qū)域的12.5%而不是10%。另外順便提及一下,每次大家看到GC日志的時候,GC日志中的每個區(qū)域的最大值,其中Yong的空間最大值,始終比設(shè)置的Yong空間的大小要小一點,大概是小12.5%左右,那是因為每次可用空間為Eden加上一個Survivor區(qū)域的大小,而不是整個Yong的大小,因為可用空間每次最多是這樣大,兩個Survivor區(qū)域始終有一塊是空的,所以不會加上兩個來計算。
-XX:MaxTenuringThreshold=15:在正常情況下,新申請的對象在Yong區(qū)域發(fā)生多少次GC后就會被移動到Old(非正常就是S0或S1放不下或者不太可能出現(xiàn)的Eden都放不下的對象),這個參數(shù)一般不會超過16(因為計數(shù)器從0開始計數(shù),所以設(shè)置為15的時候相當于生命周期為16)。
要查看現(xiàn)在的這個值的具體情況,可以使用參數(shù):-XX:+PrintTenuringDistribution
通過上面的jmap應(yīng)該可以看出我的機器上的MinHeapFreeRatio和MaxHeapFreeRatio分別為40個70,也就是大家經(jīng)常說的在GC后剩余空間小于40%時capacity開始增大,而大于70%時減小,由于我們不希望讓它移動,所以這兩個參數(shù)幾乎沒有意義,如果你需要設(shè)置就設(shè)置參數(shù)為:
-XX:MinHeapFreeRatio=40
-XX:MaxHeapFreeRatio=70
JDK 1.6后有一個動態(tài)調(diào)節(jié)板塊的,當然如果你的每一個板塊都是設(shè)置固定值,這個參數(shù)也沒有用,不過如果是非固定的,建議還是不要動態(tài)調(diào)整,默認是開啟的,建議將其關(guān)掉,參數(shù)為:
-XX:+UseAdaptiveSizepollcy 建議使用-XX:-UseAdaptiveSizepollcy關(guān)掉,為什么當你的參數(shù)設(shè)置了NewRatio、Survivor、MaxTenuringThreshold這幾個參數(shù)如果在啟動了動態(tài)更新情況下,是無效的,當然如果你設(shè)置-Xmn是有效的,但是如果設(shè)置的比例的話,初始化可能會按照你的參數(shù)去運行,不過運行過程中會通過一定的算法動態(tài)修改,監(jiān)控中你可能會發(fā)現(xiàn)這些參數(shù)會發(fā)生改變,甚至于S0和S1的大小不一樣。
如果啟動了這個參數(shù),又想要跟蹤變化,那么就使用參數(shù):-XX:+PrintAdaptiveSizePolicy
上面已經(jīng)提到,javaNIO中通過Direct內(nèi)存來提高性能,這個區(qū)域的大小默認是64M,在適當?shù)膱鼍翱梢栽O(shè)置大一些。
-XX:MaxDirectMemorySize
一個不太常用的參數(shù):
-XX:+ScavengeBeforeFullGC 默認是開啟狀態(tài),在full GC前先進行minor GC。
對于java堆中如果要設(shè)置大頁內(nèi)存,可以通過設(shè)置參數(shù):
付:此參數(shù)必須在操作系統(tǒng)的內(nèi)核支持的基礎(chǔ)上,需要在OS級別做操作為:
echo 1024 > /proc/sys/vm/nr_hugepages
echo 2147483647 > /proc/sys/kernel/shmmax
-XX:+UseLargePages
-XX:LargePageSizeInBytes
此時整個JVM都將在這塊內(nèi)存中,否則全部不在這塊內(nèi)存中。
javaIO的臨時目錄設(shè)置
-Djava.io.tmpdir
jstack會去尋找/tmp/hsperfdata_admin下去尋找與進程號相同的文件,32位機器上是沒有問題的,64為機器的是有BUG的,在jdk 1.6u23版本中已經(jīng)修復(fù)了這個bug,如果你遇到這個問題,就需要升級JDK了。
還記得上次說的平均晉升大小嗎,在并行GC時,如果平均晉升大小大于old剩余空間,則發(fā)生full GC,那么當小于剩余空間時,也就是平均晉升小于剩余空間,但是剩余空間小于eden + 一個survivor的空間時,此時就依賴于參數(shù):
-XX:-HandlePromotionFailure
啟動該參數(shù)時,上述情況成立就發(fā)生minor gc(YGC),大于則發(fā)生full gc(major gc)。
一般默認直接分配的對象如果大于Eden的一半就會直接晉升到old區(qū)域,但是也可以通過參數(shù)來指定:
-XX:PretenureSizeThreshold=2m 我個人不建議使用這個參數(shù)
也就是當申請對象大于這個值就會晉升到old區(qū)域。
傳說中GC時間的限制,一個是通過比例限制,一個是通過最大暫停時間限制,但是GC時間能限制么,呵呵,在增量中貌似可以限制,不過不能限制住GC總體的時間,所以這個參數(shù)也不是那么關(guān)鍵。
-XX:GCTimeRatio=
-XX:MaxGCPauseMillis
-XX:GCTimeLimit
要看到真正暫停的時間就一個是看GCDetail的日志,另一個是設(shè)置參數(shù)看:
-XX:+PrintGCApplicationStoppedTime
有些人,有些人就是喜歡在代碼里面里頭寫System.gc(),???,這個不是測試程序是線上業(yè)務(wù),這樣將會導(dǎo)致N多的問題,不多說了,你應(yīng)該懂的,不懂的話看下書吧,而RMI是很不聽話的一個鳥玩意,EJB的框架也是基于RMI寫的,RMI為什么不聽話呢,就是它自己在里面非要搞個System.gc(),哎,為了放置頻繁的做,頻繁的做,你就將這個命令的執(zhí)行禁用掉吧,當然程序不用改,不然那些EJB都跑步起來了,呵呵:
-XX:+DisableExplicitGC 默認是沒有禁用掉,寫成+就是禁用掉的了,但是有些時候在使用allocateDirect的時候,很多時候還真需要System.gc來強制回收這塊資源。
內(nèi)存溢出時導(dǎo)出溢出的錯誤信息:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/xieyu/logs/ 這個參數(shù)指定導(dǎo)出時的路徑,不然導(dǎo)出的路徑就是虛擬機的目標位置,不好找了,默認的文件名是:java_pid<進程號>.hprof,這個文件可以類似使用jmap -dump:file=....,format=b <pid>來dump類似的內(nèi)容,文件后綴都是hprof,然后下載mat工具進行分析即可(不過內(nèi)存有多大dump文件就多大,而本地分析的時候內(nèi)存也需要那么大,所以很多時候下載到本地都無法啟動是很正常的),后續(xù)文章有機會我們來說明這些工具,另外jmap -dump參數(shù)也不要經(jīng)常用,會導(dǎo)致應(yīng)用掛起哦;另外此參數(shù)只會在第一次輸出OOM的時候才會進行堆的dump操作(java heap的溢出是可以繼續(xù)運行再運行的程序的,至于web應(yīng)用是否服務(wù)要看應(yīng)用服務(wù)器自身如何處理,而c heap區(qū)域的溢出就根本沒有dump的機會,因為直接就宕機了,目前系統(tǒng)無法看到c heap的大小以及內(nèi)部變化,要看大小只能間接通過看JVM進程的內(nèi)存大?。?strong>top或類似參數(shù)),這個大小一般會大于heap+perm的大小,多余的部分基本就可以認為是c heap的大小了,而看內(nèi)部變化呢只有google perftools可以達到這個目的),如果內(nèi)存過大這個dump操作將會非常長,所以hotspot如果以后想管理大內(nèi)存,這塊必須有新的辦法出來。
最后,用dump出來的文件,通過mat分析出來的結(jié)果往往有些時候難以直接確定到底哪里有問題,可以看到的維度大概有:那個類使用的內(nèi)存最多,以及每一個線程使用的內(nèi)存,以及線程內(nèi)部每一個調(diào)用的類和方法所使用的內(nèi)存,但是很多時候無法判定到底是程序什么地方調(diào)用了這個類或者方法,因為這里只能看到最終消耗內(nèi)存的類,但是不知道誰使用了它,一個辦法是掃描代碼,但是太笨重,而且如果是jar包中調(diào)用了就不好弄了,另一種方法是寫agent,那么就需要相應(yīng)的配合了,但是有一個非常好的工具就是btrace工具(jdk 1.7貌似還不支持),可以跟蹤到某個類的某個方法被那些類中的方法調(diào)用過,那這個問題就好說了,只要知道開銷內(nèi)存的是哪一個類,就能知道誰調(diào)用過它,OK,關(guān)于btrace的不是本文重點,網(wǎng)上都有,后續(xù)文章有機會再探討,
原理:
No performance impact during runtime(無性能影響)
Dumping a –Xmx512m heap
Create a 512MB .hprof file(512M內(nèi)存就dump出512M的空間大小)
JVM is “dead” during dumping(死掉時dump)
Restarting JVM during this dump will cause unusable .hprof file(重啟導(dǎo)致文件不可用)
注明的NUMA架構(gòu),在JVM中開始支持,當然也需要CPU和OS的支持才可以,需要設(shè)置參數(shù)為:
-XX:+UseNUMA 必須在并行GC的基礎(chǔ)上才有的
老年代無法分配區(qū)域的最大等待時間為(默認值為0,但是也不要去動它):
-XX:GCExpandToAllocateDelayMillis
讓JVM中所有的set和get方法轉(zhuǎn)換為本地代碼:
-XX:+UseFastAccessorMethods
以時間戳輸出Heap的利用率
-XX:+PrintHeapUsageOverTime
在64bit的OS上面(其實一般達不到57位左右),由于指針會放大為8個byte,所以會導(dǎo)致空間使用增加,當然,如果內(nèi)存夠大,就沒有問題,但是如果升級到64bit系統(tǒng)后,只是想讓內(nèi)存達到4G或者8G,那么就完全可以通過很多指針壓縮為4byte就OK了,所以在提供以下參數(shù)(本參數(shù)于jdk 1.6u23后使用,并自動開啟,所以也不需要你設(shè)置,知道就OK):
-XX:+UseCompressedOops 請注意:這個參數(shù)默認在64bit的環(huán)境下默認啟動,但是如果JVM的內(nèi)存達到32G后,這個參數(shù)就會默認為不啟動,因為32G內(nèi)存后,壓縮就沒有多大必要了,要管理那么大的內(nèi)存指針也需要很大的寬度了。
后臺JIT編譯優(yōu)化啟動
-XX:+BackgroundCompilation
如果你要輸出GC的日志以及時間戳,相關(guān)的參數(shù)有:
-XX:+PrintGCDetails 輸出GC的日志詳情,包含了時間戳
-XX:+PrintGCTimeStamps 輸出GC的時間戳信息,按照啟動JVM后相對時間的每次GC的相對秒值(毫秒在小數(shù)點后面),也就是每次GC相對啟動JVM啟動了多少秒后發(fā)生了這次GC
-XX:+PrintGCDateStamps輸出GC的時間信息,會按照系統(tǒng)格式的日期輸出每次GC的時間
-XX:+PrintGCTaskTimeStamps輸出任務(wù)的時間戳信息,這個細節(jié)上比較復(fù)雜,后續(xù)有文章來探討。
-XX:-TraceClassLoading 跟蹤類的裝載
-XX:-TraceClassUnloading 跟蹤類的卸載
-XX:+PrintHeapAtGC 輸出GC后各個堆板塊的大小。
將常量信息GC信息輸出到日志文件:
-Xloggc:/home/xieyu/logs/gc.log
現(xiàn)在面對大內(nèi)存比較流行是是CMS GC(最少1.5才支持),首先明白CMS的全稱是什么,不是傳統(tǒng)意義上的內(nèi)容管理系統(tǒng)(Content Management System)哈,第一次我也沒看懂,它的全稱是:Concurrent Mark Sweep,三個單詞分別代表并發(fā)、標記、清掃(主意這里沒有compact操作,其實CMS GC的確沒有compact操作),也就是在程序運行的同時進行標記和清掃工作,至于它的原理前面有提及過,只是有不同的廠商在上面做了一些特殊的優(yōu)化,比如一些廠商在標記根節(jié)點的過程中,標記完當前的根,那么這個根下面的內(nèi)容就不會被暫?;謴?fù)運行了,而移動過程中,通過讀屏障來看這個內(nèi)存是不是發(fā)生移動,如果在移動稍微停一下,移動過去后再使用,hotspot還沒這么厲害,暫停時間還是挺長的,只是相對其他的GC策略在面對大內(nèi)存來講是不錯的選擇。
下面看一些CMS的策略(并發(fā)GC總時間會比常規(guī)的并行GC長,因為它是在運行時去做GC,很多資源征用都會影響其GC的效率,而總體的暫停時間會短暫很多很多,其并行線程數(shù)默認為:(上面設(shè)置的并行線程數(shù) + 3)/ 4
付:CMS是目前Hotspot管理大內(nèi)存最好的JVM,如果是常規(guī)的JVM,最佳選擇為ParallelOldGC,如果必須要以響應(yīng)時間為準,則選擇CMS,不過CMS有兩個隱藏的隱患:
1、CMS GC雖然是并發(fā)且并行運行的GC,但是初始化的時候如果采用默認值92%(JVM 1.5的白皮書上描述為68%其實是錯誤的,1.6是正確的),就很容易出現(xiàn)問題,因為CMS GC僅僅針對Old區(qū)域,Yong區(qū)域使用ParNew算法,也就是Old的CMS回收和Yong的回收可以同時進行,也就是回收過程中Yong有可能會晉升對象Old,并且業(yè)務(wù)也可以同時運行,所以92%基本開始啟動CMS GC很有可能old的內(nèi)存就不夠用了,當內(nèi)存不夠用的時候,就啟動Full GC,并且這個Full GC是串行的,所以如果弄的不好,CMS會比并行GC更加慢,為什么要啟用串行是因為CMS GC、并行GC、串行GC的繼承關(guān)系決定的,簡單說就是它沒辦法去調(diào)用并行GC的代碼,細節(jié)說后續(xù)有文章來細節(jié)說明),建議這個值設(shè)置為70%左右吧,不過具體時間還是自己決定。
2、CMS GC另一個大的隱患,其實不看也差不多應(yīng)該清楚,看名字就知道,就是不會做Compact操作,它最惡心的地方也在這里,所以上面才說一般的應(yīng)用都不使用它,它只有內(nèi)存垃圾非常多,多得無法分配晉升的空間的時候才會出現(xiàn)一次compact,但是這個是Full GC,也就是上面的串行,很恐怖的,所以內(nèi)存不是很大的,不要考慮使用它,而且它的算法十分復(fù)雜。
還有一些小的隱患是:和應(yīng)用一起征用CPU(不過這個不是大問題,增加CPU即可)、整個運行過程中時間比并行GC長(這個也不是大問題,因為我們更加關(guān)心暫停時間而不是運行時間,因為暫停會影響非常多的業(yè)務(wù))。
啟動CMS為全局GC方法(注意這個參數(shù)也不能上面的并行GC進行混淆,Yong默認是并行的,上面已經(jīng)說過
-XX:+UseConcMarkSweepGC
在并發(fā)GC下啟動增量模式,只能在CMS GC下這個參數(shù)才有效。
-XX:+CMSIncrementalMode
啟動自動調(diào)節(jié)duty cycle,即在CMS GC中發(fā)生的時間比率設(shè)置,也就是說這段時間內(nèi)最大允許發(fā)生多長時間的GC工作是可以調(diào)整的。
-XX:+CMSIncrementalPacing
在上面這個參數(shù)設(shè)定后可以分別設(shè)置以下兩個參數(shù)(參數(shù)設(shè)置的比率,范圍為0-100):
-XX:CMSIncrementalDutyCycleMin=0
-XX:CMSIncrementalDutyCycle=10
增量GC上還有一個保護因子(CMSIncrementalSafetyFactor),不太常用;CMSIncrementalOffset提供增量GC連續(xù)時間比率的設(shè)置;CMSExpAvgFactor為增量并發(fā)的GC增加權(quán)重計算。
-XX:CMSIncrementalSafetyFactor=
-XX:CMSIncrementalOffset=
-XX:CMSExpAvgFactor=
是否啟動并行CMS GC(默認也是開啟的)
-XX:+CMSParallelRemarkEnabled
要單獨對CMS GC設(shè)置并行線程數(shù)就設(shè)置(默認也不需要設(shè)置):
-XX:ParallelCMSThreads
對PernGen進行垃圾回收:
JDK 1.5在CMS GC基礎(chǔ)上需要設(shè)置參數(shù)(也就是前提是CMS GC才有):
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
1.6以后的版本無需設(shè)置:-XX:+CMSPermGenSweepingEnabled,注意,其實一直以來Full GC都會觸發(fā)對Perm的回收過程,CMS GC需要有一些特殊照顧,雖然VM會對這塊區(qū)域回收,但是Perm回收的條件幾乎不太可能實現(xiàn),首先需要這個類的classloader必須死掉,才可以將該classloader下所有的class干掉,也就是要么全部死掉,要么全部活著;另外,這個classloader下的class沒有任何object在使用,這個也太苛刻了吧,因為常規(guī)的對象申請都是通過系統(tǒng)默認的,應(yīng)用服務(wù)器也有自己默認的classloader,要讓它死掉可能性不大,如果這都死掉了,系統(tǒng)也應(yīng)該快掛了。
CMS GC因為是在程序運行時進行GC,不會暫停,所以不能等到不夠用的時候才去開啟GC,官方說法是他們的默認值是68%,但是可惜的是文檔寫錯了,經(jīng)過很多測試和源碼驗證這個參數(shù)應(yīng)該是在92%的時候被啟動,雖然還有8%的空間,但是還是很可憐了,當CMS發(fā)現(xiàn)內(nèi)存實在不夠的時候又回到常規(guī)的并行GC,所以很多人在沒有設(shè)置這個參數(shù)的時候發(fā)現(xiàn)CMS GC并沒有神馬優(yōu)勢嘛,和并行GC一個鳥樣子甚至于更加慢,所以這個時候需要設(shè)置參數(shù)(這個參數(shù)在上面已經(jīng)說過,啟動CMS一定要設(shè)置這個參數(shù)):
-XX:CMSInitiatingOccupancyFraction=70
這樣保證Old的內(nèi)存在使用到70%的時候,就開始啟動CMS了;如果你真的想看看默認值,那么就使用參數(shù):-XX:+PrintCMSInitiationStatistics 這個變量只有JDK 1.6可以使用 1.5不可以,查看實際值-XX:+PrintCMSStatistics;另外,還可以設(shè)置參數(shù)-XX:CMSInitiatingPermOccupancyFraction來設(shè)置Perm空間達到多少時啟動CMS GC,不過意義不大。
JDK 1.6以后有些時候啟動CMS GC是根據(jù)計算代價進行啟動,也就是不一定按照你指定的參數(shù)來設(shè)置的,如果你不想讓它按照所謂的成本來計算GC的話,那么你就使用一個參數(shù):-XX:+UseCMSInitiatingOccupancyOnly,默認是false,它就只會按照你設(shè)置的比率來啟動CMS GC了。如果你的程序中有System.gc以及設(shè)置了ExplicitGCInvokesConcurrent在jdk 1.6中,這種情況使用NIO是有可能產(chǎn)生問題的。
啟動CMS GC的compation操作,也就是發(fā)生多少次后做一次全局的compaction:
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction:發(fā)生多少次CMS Full GC,這個參數(shù)最好不要設(shè)置,因為要做compaction的話,也就是真正的Full GC是串行的,非常慢,讓它自己去決定什么時候需要做compaction。
-XX:CMSMaxAbortablePrecleanTime=5000 設(shè)置preclean步驟的超時時間,單位為毫秒,preclean為cms gc其中一個步驟,關(guān)于cms gc步驟比較多,本文就不細節(jié)探討了。
并行GC在mark階段,可能會同時發(fā)生minor GC,old區(qū)域也可能發(fā)生改變,于是并發(fā)GC會對發(fā)生了改變的內(nèi)容進行remark操作,這個觸發(fā)的條件是:
-XX:CMSScheduleRemarkEdenSizeThreshold
-XX:CMSScheduleRemarkEdenPenetration
即Eden區(qū)域多大的時候開始觸發(fā),和eden使用量超過百分比多少的時候觸發(fā),前者默認是2M,后者默認是50%。
但是如果長期不做remark導(dǎo)致old做不了,可以設(shè)置超時,這個超時默認是5秒,可以通過參數(shù):
-XX:CMSMaxAbortablePrecleanTime
-XX:+ExplicitGCInvokesConcurrent 在顯示發(fā)生GC的時候,允許進行并行GC。
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses 幾乎和上面一樣,只不過多一個對Perm區(qū)域的回收而已。
補充:
其實JVM還有很多的版本,很多的廠商,與其優(yōu)化的原則,隨便舉兩個例子hotspot在GC中做的一些優(yōu)化(這里不說代碼的編譯時優(yōu)化或運行時優(yōu)化):
Eden申請的空間對象由Old區(qū)域的某個對象的一個屬性指向(也就是Old區(qū)域的這個空間不回收,Eden這塊就沒有必要考慮回收),所以Hotspot在CPU寫上面,做了一個屏障,當發(fā)生賦值語句的時候(對內(nèi)存來講賦值就是一種寫操作),如果發(fā)現(xiàn)是一個新的對象由Old指向Eden,那么就會將這個對象記錄在一個卡片機里面,這個卡片機是有很多512字節(jié)的卡片組成,當在YGC過程中,就基本不會去移動或者管理這塊對象(付:這種卡片機會在CMS GC的算法中使用,不過和這個卡片不是放在同一個地方的,也是CMS GC的關(guān)鍵,對于CMS GC的算法細節(jié)描述,后續(xù)文章我們單獨說明)。
Old區(qū)域?qū)τ谝恍┍容^大的對象,JVM就不會去管理個對象,也就是compact過程中不會去移動這塊對象的區(qū)域等等吧。
以上大部分參數(shù)為hotspot的自帶關(guān)于性能的參數(shù),參考版本為JDK 1.5和1.6的版本,很多為個人經(jīng)驗說明,不足以說明所有問題,如果有問題,歡迎探討;另外,JDK的參數(shù)是不是就只有這些呢,肯定并不是,我知道的也不止這些,但是有些覺得沒必要說出來的參數(shù)和一些數(shù)學運算的參數(shù)我就不想給出來了,比如像禁用掉GC的參數(shù)有神馬意義,我們的服務(wù)器要是把這個禁用掉干個屁啊,呵呵,做測試還可以用這玩玩,讓它不做GC直接溢出;還有一些什么計算因子啥的,還有很多復(fù)雜的數(shù)學運算規(guī)則,要是把這個配置明白了,就太那個了,而且一般情況下也沒那個必要,JDK到現(xiàn)在的配置參數(shù)多達上500個以上,要知道完的話慢慢看吧,不過意義不大,而且要知道默認值最靠譜的是看源碼而不是看文檔,官方文檔也只能保證絕大部是正確的,不能保證所有的是正確的。
本文最后追加在jdk 1.6u 24后通過上面說明的-XX:+PrintFlagsFinal輸出的參數(shù)以及默認值(還是那句話,在不同的平臺上是不一樣的),輸出的參數(shù)如下,可以看看JVM的參數(shù)是相當?shù)亩?,參?shù)如此之多,你只需要掌握關(guān)鍵即可,參數(shù)還有很多有沖突的,不要糾結(jié)于每一個參數(shù)的細節(jié):
$java -XX:+PrintFlagsFinal
uintx AdaptivePermSizeWeight = 20 {product} uintx AdaptiveSizeDecrementScaleFactor = 4 {product} uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product} uintx AdaptiveSizePausePolicy = 0 {product} uintx AdaptiveSizePolicyCollectionCostMargin = 50 {product} uintx AdaptiveSizePolicyInitializingSteps = 20 {product} uintx AdaptiveSizePolicyOutputInterval = 0 {product} uintx AdaptiveSizePolicyWeight = 10 {product} uintx AdaptiveSizeThroughPutPolicy = 0 {product} uintx AdaptiveTimeWeight = 25 {product} bool AdjustConcurrency = false {product} bool AggressiveOpts = false {product} intx AliasLevel = 3 {product} intx AllocatePrefetchDistance = -1 {product} intx AllocatePrefetchInstr = 0 {product} intx AllocatePrefetchLines = 1 {product} intx AllocatePrefetchStepSize = 16 {product} intx AllocatePrefetchStyle = 1 {product} bool AllowJNIEnvProxy = false {product} bool AllowParallelDefineClass = false {product} bool AllowUserSignalHandlers = false {product} bool AlwaysActAsServerClassMachine = false {product} bool AlwaysCompileLoopMethods = false {product} intx AlwaysInflate = 0 {product} bool AlwaysLockClassLoader = false {product} bool AlwaysPreTouch = false {product} bool AlwaysRestoreFPU = false {product} bool AlwaysTenure = false {product} bool AnonymousClasses = false {product} bool AssertOnSuspendWaitFailure = false {product} intx Atomics = 0 {product} uintx AutoGCSelectPauseMillis = 5000 {product} intx BCEATraceLevel = 0 {product} intx BackEdgeThreshold = 100000 {pd product} bool BackgroundCompilation = true {pd product} uintx BaseFootPrintEstimate = 268435456 {product} intx BiasedLockingBulkRebiasThreshold = 20 {product} intx BiasedLockingBulkRevokeThreshold = 40 {product} intx BiasedLockingDecayTime = 25000 {product} intx BiasedLockingStartupDelay = 4000 {product} bool BindGCTaskThreadsToCPUs = false {product} bool BlockOffsetArrayUseUnallocatedBlock = false {product} bool BytecodeVerificationLocal = false {product} bool BytecodeVerificationRemote = true {product} intx CICompilerCount = 1 {product} bool CICompilerCountPerCPU = false {product} bool CITime = false {product} bool CMSAbortSemantics = false {product} uintx CMSAbortablePrecleanMinWorkPerIteration = 100 {product} intx CMSAbortablePrecleanWaitMillis = 100 {product} uintx CMSBitMapYieldQuantum = 10485760 {product} uintx CMSBootstrapOccupancy = 50 {product} bool CMSClassUnloadingEnabled = false {product} uintx CMSClassUnloadingMaxInterval = 0 {product} bool CMSCleanOnEnter = true {product} bool CMSCompactWhenClearAllSoftRefs = true {product} uintx CMSConcMarkMultiple = 32 {product} bool CMSConcurrentMTEnabled = true {product} uintx CMSCoordinatorYieldSleepCount = 10 {product} bool CMSDumpAtPromotionFailure = false {product} uintx CMSExpAvgFactor = 50 {product} bool CMSExtrapolateSweep = false {product} uintx CMSFullGCsBeforeCompaction = 0 {product} uintx CMSIncrementalDutyCycle = 10 {product} uintx CMSIncrementalDutyCycleMin = 0 {product} bool CMSIncrementalMode = false {product} uintx CMSIncrementalOffset = 0 {product} bool CMSIncrementalPacing = true {product} uintx CMSIncrementalSafetyFactor = 10 {product} uintx CMSIndexedFreeListReplenish = 4 {product} intx CMSInitiatingOccupancyFraction = -1 {product} intx CMSInitiatingPermOccupancyFraction = -1 {product} intx CMSIsTooFullPercentage = 98 {product} double CMSLargeCoalSurplusPercent = {product} double CMSLargeSplitSurplusPercent = {product} bool CMSLoopWarn = false {product} uintx CMSMaxAbortablePrecleanLoops = 0 {product} intx CMSMaxAbortablePrecleanTime = 5000 {product} uintx CMSOldPLABMax = 1024 {product} uintx CMSOldPLABMin = 16 {product} uintx CMSOldPLABNumRefills = 4 {product} uintx CMSOldPLABReactivityCeiling = 10 {product} uintx CMSOldPLABReactivityFactor = 2 {product} bool CMSOldPLABResizeQuicker = false {product} uintx CMSOldPLABToleranceFactor = 4 {product} bool CMSPLABRecordAlways = true {product} uintx CMSParPromoteBlocksToClaim = 16 {product} bool CMSParallelRemarkEnabled = true {product} bool CMSParallelSurvivorRemarkEnabled = true {product} bool CMSPermGenPrecleaningEnabled = true {product} uintx CMSPrecleanDenominator = 3 {product} uintx CMSPrecleanIter = 3 {product} uintx CMSPrecleanNumerator = 2 {product} bool CMSPrecleanRefLists1 = true {product} bool CMSPrecleanRefLists2 = false {product} bool CMSPrecleanSurvivors1 = false {product} bool CMSPrecleanSurvivors2 = true {product} uintx CMSPrecleanThreshold = 1000 {product} bool CMSPrecleaningEnabled = true {product} bool CMSPrintChunksInDump = false {product} bool CMSPrintObjectsInDump = false {product} uintx CMSRemarkVerifyVariant = 1 {product} bool CMSReplenishIntermediate = true {product} uintx CMSRescanMultiple = 32 {product} uintx CMSRevisitStackSize = 1048576 {product} uintx CMSSamplingGrain = 16384 {product} bool CMSScavengeBeforeRemark = false {product} uintx CMSScheduleRemarkEdenPenetration = 50 {product} uintx CMSScheduleRemarkEdenSizeThreshold = 2097152 {product} uintx CMSScheduleRemarkSamplingRatio = 5 {product} double CMSSmallCoalSurplusPercent = {product} double CMSSmallSplitSurplusPercent = {product} bool CMSSplitIndexedFreeListBlocks = true {product} intx CMSTriggerPermRatio = 80 {product} intx CMSTriggerRatio = 80 {product} bool CMSUseOldDefaults = false {product} intx CMSWaitDuration = 2000 {product} uintx CMSWorkQueueDrainThreshold = 10 {product} bool CMSYield = true {product} uintx CMSYieldSleepCount = 0 {product} intx CMSYoungGenPerWorker = 16777216 {product} uintx CMS_FLSPadding = 1 {product} uintx CMS_FLSWeight = 75 {product} uintx CMS_SweepPadding = 1 {product} uintx CMS_SweepTimerThresholdMillis = 10 {product} uintx CMS_SweepWeight = 75 {product} bool CheckJNICalls = false {product} bool ClassUnloading = true {product} intx ClearFPUAtPark = 0 {product} bool ClipInlining = true {product} uintx CodeCacheExpansionSize = 32768 {pd product} uintx CodeCacheFlushingMinimumFreeSpace = 1536000 {product} uintx CodeCacheMinimumFreeSpace = 512000 {product} bool CollectGen0First = false {product} bool CompactFields = true {product} intx CompilationPolicyChoice = 0 {product} intx CompilationRepeat = 0 {C1 product} ccstrlist CompileCommand = {product} ccstr CompileCommandFile = {product} ccstrlist CompileOnly = {product} intx CompileThreshold = 1500 {pd product} bool CompilerThreadHintNoPreempt = true {product} intx CompilerThreadPriority = -1 {product} intx CompilerThreadStackSize = 0 {pd product} uintx ConcGCThreads = 0 {product} bool ConvertSleepToYield = true {pd product} bool ConvertYieldToSleep = false {product} bool DTraceAllocProbes = false {product} bool DTraceMethodProbes = false {product} bool DTraceMonitorProbes = false {product} uintx DefaultMaxRAMFraction = 4 {product} intx DefaultThreadPriority = -1 {product} intx DeferPollingPageLoopCount = -1 {product} intx DeferThrSuspendLoopCount = 4000 {product} bool DeoptimizeRandom = false {product} bool DisableAttachMechanism = false {product} bool DisableExplicitGC = false {product} bool DisplayVMOutputToStderr = false {product} bool DisplayVMOutputToStdout = false {product} bool DontCompileHugeMethods = true {product} bool DontYieldALot = false {pd product} bool DumpSharedSpaces = false {product} bool EagerXrunInit = false {product} intx EmitSync = 0 {product} uintx ErgoHeapSizeLimit = 0 {product} ccstr ErrorFile = {product} bool EstimateArgEscape = true {product} intx EventLogLength = 2000 {product} bool ExplicitGCInvokesConcurrent = false {product} bool ExplicitGCInvokesConcurrentAndUnloadsClasses = false {produ bool ExtendedDTraceProbes = false {product} bool FLSAlwaysCoalesceLarge = false {product} uintx FLSCoalescePolicy = 2 {product} double FLSLargestBlockCoalesceProximity = {product} bool FailOverToOldVerifier = true {product} bool FastTLABRefill = true {product} intx FenceInstruction = 0 {product} intx FieldsAllocationStyle = 1 {product} bool FilterSpuriousWakeups = true {product} bool ForceFullGCJVMTIEpilogues = false {product} bool ForceNUMA = false {product} bool ForceSharedSpaces = false {product} bool ForceTimeHighResolution = false {product} intx FreqInlineSize = 325 {pd product} intx G1ConcRefinementGreenZone = 0 {product} intx G1ConcRefinementRedZone = 0 {product} intx G1ConcRefinementServiceIntervalMillis = 300 {product} uintx G1ConcRefinementThreads = 0 {product} intx G1ConcRefinementThresholdStep = 0 {product} intx G1ConcRefinementYellowZone = 0 {product} intx G1ConfidencePercent = 50 {product} uintx G1HeapRegionSize = 0 {product} intx G1MarkRegionStackSize = 1048576 {product} intx G1RSetRegionEntries = 0 {product} uintx G1RSetScanBlockSize = 64 {product} intx G1RSetSparseRegionEntries = 0 {product} intx G1RSetUpdatingPauseTimePercent = 10 {product} intx G1ReservePercent = 10 {product} intx G1SATBBufferSize = 1024 {product} intx G1UpdateBufferSize = 256 {product} bool G1UseAdaptiveConcRefinement = true {product} bool G1UseFixedWindowMMUTracker = false {product} uintx GCDrainStackTargetSize = 64 {product} uintx GCHeapFreeLimit = 2 {product} bool GCLockerInvokesConcurrent = false {product} bool GCOverheadReporting = false {product} intx GCOverheadReportingPeriodMS = 100 {product} intx GCPauseIntervalMillis = 500 {product} uintx GCTaskTimeStampEntries = 200 {product} uintx GCTimeLimit = 98 {product} uintx GCTimeRatio = 99 {product} ccstr HPILibPath = {product} bool HandlePromotionFailure = true {product} uintx HeapBaseMinAddress = 2147483648 {pd product} bool HeapDumpAfterFullGC = false {manageable} bool HeapDumpBeforeFullGC = false {manageable} bool HeapDumpOnOutOfMemoryError = false {manageable} ccstr HeapDumpPath = {manageable} uintx HeapFirstMaximumCompactionCount = 3 {product} uintx HeapMaximumCompactionInterval = 20 {product} bool IgnoreUnrecognizedVMOptions = false {product} uintx InitialCodeCacheSize = 163840 {pd product} uintx InitialHeapSize := 16777216 {product} uintx InitialRAMFraction = 64 {product} uintx InitialSurvivorRatio = 8 {product} intx InitialTenuringThreshold = 7 {product} uintx InitiatingHeapOccupancyPercent = 45 {product} bool Inline = true {product} intx InlineSmallCode = 1000 {pd product} intx InterpreterProfilePercentage = 33 {product} bool JNIDetachReleasesMonitors = true {product} bool JavaMonitorsInStackTrace = true {product} intx JavaPriority10_To_OSPriority = -1 {product} intx JavaPriority1_To_OSPriority = -1 {product} intx JavaPriority2_To_OSPriority = -1 {product} intx JavaPriority3_To_OSPriority = -1 {product} intx JavaPriority4_To_OSPriority = -1 {product} intx JavaPriority5_To_OSPriority = -1 {product} intx JavaPriority6_To_OSPriority = -1 {product} intx JavaPriority7_To_OSPriority = -1 {product} intx JavaPriority8_To_OSPriority = -1 {product} intx JavaPriority9_To_OSPriority = -1 {product} bool LIRFillDelaySlots = false {C1 pd product} uintx LargePageHeapSizeThreshold = 134217728 {product} uintx LargePageSizeInBytes = 0 {product} bool LazyBootClassLoader = true {product} bool ManagementServer = false {product} uintx MarkStackSize = 32768 {product} uintx MarkStackSizeMax = 4194304 {product} intx MarkSweepAlwaysCompactCount = 4 {product} uintx MarkSweepDeadRatio = 5 {product} intx MaxBCEAEstimateLevel = 5 {product} intx MaxBCEAEstimateSize = 150 {product} intx MaxDirectMemorySize = -1 {product} bool MaxFDLimit = true {product} uintx MaxGCMinorPauseMillis = 4294967295 {product} uintx MaxGCPauseMillis = 4294967295 {product} uintx MaxHeapFreeRatio = 70 {product} uintx MaxHeapSize := 268435456 {product} intx MaxInlineLevel = 9 {product} intx MaxInlineSize = 35 {product} intx MaxJavaStackTraceDepth = 1024 {product} uintx MaxLiveObjectEvacuationRatio = 100 {product} uintx MaxNewSize = 4294967295 {product} uintx MaxPermHeapExpansion = 4194304 {product} uintx MaxPermSize = 67108864 {pd product} uint64_t MaxRAM = 1073741824 {pd product} uintx MaxRAMFraction = 4 {product} intx MaxRecursiveInlineLevel = 1 {product} intx MaxTenuringThreshold = 15 {product} intx MaxTrivialSize = 6 {product} bool MethodFlushing = true {product} intx MinCodeCacheFlushingInterval = 30 {product} uintx MinHeapDeltaBytes = 131072 {product} uintx MinHeapFreeRatio = 40 {product} intx MinInliningThreshold = 250 {product} uintx MinPermHeapExpansion = 262144 {product} uintx MinRAMFraction = 2 {product} uintx MinSurvivorRatio = 3 {product} uintx MinTLABSize = 2048 {product} intx MonitorBound = 0 {product} bool MonitorInUseLists = false {product} bool MustCallLoadClassInternal = false {product} intx NUMAChunkResizeWeight = 20 {product} intx NUMAPageScanRate = 256 {product} intx NUMASpaceResizeRate = 1073741824 {product} bool NUMAStats = false {product} intx NativeMonitorFlags = 0 {product} intx NativeMonitorSpinLimit = 20 {product} intx NativeMonitorTimeout = -1 {product} bool NeedsDeoptSuspend = false {pd product} bool NeverActAsServerClassMachine = true {pd product} bool NeverTenure = false {product} intx NewRatio = 2 {product} uintx NewSize = 1048576 {product} uintx NewSizeThreadIncrease = 4096 {pd product} intx NmethodSweepFraction = 4 {product} uintx OldPLABSize = 1024 {product} uintx OldPLABWeight = 50 {product} uintx OldSize = 4194304 {product} bool OmitStackTraceInFastThrow = true {product} ccstrlist OnError = {product} ccstrlist OnOutOfMemoryError = {product} intx OnStackReplacePercentage = 933 {pd product} uintx PLABWeight = 75 {product} bool PSChunkLargeArrays = true {product} intx ParGCArrayScanChunk = 50 {product} uintx ParGCDesiredObjsFromOverflowList = 20 {product} bool ParGCTrimOverflow = true {product} bool ParGCUseLocalOverflow = false {product} intx ParallelGCBufferWastePct = 10 {product} bool ParallelGCRetainPLAB = true {product} uintx ParallelGCThreads = 0 {product} bool ParallelGCVerbose = false {product} uintx ParallelOldDeadWoodLimiterMean = 50 {product} uintx ParallelOldDeadWoodLimiterStdDev = 80 {product} bool ParallelRefProcBalancingEnabled = true {product} bool ParallelRefProcEnabled = false {product} uintx PausePadding = 1 {product} intx PerBytecodeRecompilationCutoff = 200 {product} intx PerBytecodeTrapLimit = 4 {product} intx PerMethodRecompilationCutoff = 400 {product} intx PerMethodTrapLimit = 100 {product} bool PerfAllowAtExitRegistration = false {product} bool PerfBypassFileSystemCheck = false {product} intx PerfDataMemorySize = 32768 {product} intx PerfDataSamplingInterval = 50 {product} ccstr PerfDataSaveFile = {product} bool PerfDataSaveToFile = false {product} bool PerfDisableSharedMem = false {product} intx PerfMaxStringConstLength = 1024 {product} uintx PermGenPadding = 3 {product} uintx PermMarkSweepDeadRatio = 20 {product} uintx PermSize = 12582912 {pd product} bool PostSpinYield = true {product} intx PreBlockSpin = 10 {product} intx PreInflateSpin = 10 {pd product} bool PreSpinYield = false {product} bool PreferInterpreterNativeStubs = false {pd product} intx PrefetchCopyIntervalInBytes = -1 {product} intx PrefetchFieldsAhead = -1 {product} intx PrefetchScanIntervalInBytes = -1 {product} bool PreserveAllAnnotations = false {product} uintx PreserveMarkStackSize = 1024 {product} uintx PretenureSizeThreshold = 0 {product} bool PrintAdaptiveSizePolicy = false {product} bool PrintCMSInitiationStatistics = false {product} intx PrintCMSStatistics = 0 {product} bool PrintClassHistogram = false {manageable} bool PrintClassHistogramAfterFullGC = false {manageable} bool PrintClassHistogramBeforeFullGC = false {manageable} bool PrintCommandLineFlags = false {product} bool PrintCompilation = false {product} bool PrintConcurrentLocks = false {manageable} intx PrintFLSCensus = 0 {product} intx PrintFLSStatistics = 0 {product} bool PrintFlagsFinal := true {product} bool PrintFlagsInitial = false {product} bool PrintGC = false {manageable} bool PrintGCApplicationConcurrentTime = false {product} bool PrintGCApplicationStoppedTime = false {product} bool PrintGCDateStamps = false {manageable} bool PrintGCDetails = false {manageable} bool PrintGCTaskTimeStamps = false {product} bool PrintGCTimeStamps = false {manageable} bool PrintHeapAtGC = false {product rw} bool PrintHeapAtGCExtended = false {product rw} bool PrintHeapAtSIGBREAK = true {product} bool PrintJNIGCStalls = false {product} bool PrintJNIResolving = false {product} bool PrintOldPLAB = false {product} bool PrintPLAB = false {product} bool PrintParallelOldGCPhaseTimes = false {product} bool PrintPromotionFailure = false {product} bool PrintReferenceGC = false {product} bool PrintRevisitStats = false {product} bool PrintSafepointStatistics = false {product} intx PrintSafepointStatisticsCount = 300 {product} intx PrintSafepointStatisticsTimeout = -1 {product} bool PrintSharedSpaces = false {product} bool PrintTLAB = false {product} bool PrintTenuringDistribution = false {product} bool PrintVMOptions = false {product} bool PrintVMQWaitTime = false {product} uintx ProcessDistributionStride = 4 {product} bool ProfileInterpreter = false {pd product} bool ProfileIntervals = false {product} intx ProfileIntervalsTicks = 100 {product} intx ProfileMaturityPercentage = 20 {product} bool ProfileVM = false {product} bool ProfilerPrintByteCodeStatistics = false {product} bool ProfilerRecordPC = false {product} uintx PromotedPadding = 3 {product} intx QueuedAllocationWarningCount = 0 {product} bool RangeCheckElimination = true {product} intx ReadPrefetchInstr = 0 {product} intx ReadSpinIterations = 100 {product} bool ReduceSignalUsage = false {product} intx RefDiscoveryPolicy = 0 {product} bool ReflectionWrapResolutionErrors = true {product} bool RegisterFinalizersAtInit = true {product} bool RelaxAccessControlCheck = false {product} bool RequireSharedSpaces = false {product} uintx ReservedCodeCacheSize = 33554432 {pd product} bool ResizeOldPLAB = true {product} bool ResizePLAB = true {product} bool ResizeTLAB = true {pd product} bool RestoreMXCSROnJNICalls = false {product} bool RewriteBytecodes = false {pd product} bool RewriteFrequentPairs = false {pd product} intx SafepointPollOffset = 256 {C1 pd product} intx SafepointSpinBeforeYield = 2000 {product} bool SafepointTimeout = false {product} intx SafepointTimeoutDelay = 10000 {product} bool ScavengeBeforeFullGC = true {product} intx SelfDestructTimer = 0 {product} uintx SharedDummyBlockSize = 536870912 {product} uintx SharedMiscCodeSize = 4194304 {product} uintx SharedMiscDataSize = 4194304 {product} uintx SharedReadOnlySize = 10485760 {product} uintx SharedReadWriteSize = 12582912 {product} bool ShowMessageBoxOnError = false {product} intx SoftRefLRUPolicyMSPerMB = 1000 {product} bool SplitIfBlocks = true {product} intx StackRedPages = 1 {pd product} intx StackShadowPages = 3 {pd product} bool StackTraceInThrowable = true {product} intx StackYellowPages = 2 {pd product} bool StartAttachListener = false {product} intx StarvationMonitorInterval = 200 {product} bool StressLdcRewrite = false {product} bool StressTieredRuntime = false {product} bool SuppressFatalErrorMessage = false {product} uintx SurvivorPadding = 3 {product} intx SurvivorRatio = 8 {product} intx SuspendRetryCount = 50 {product} intx SuspendRetryDelay = 5 {product} intx SyncFlags = 0 {product} ccstr SyncKnobs = {product} intx SyncVerbose = 0 {product} uintx TLABAllocationWeight = 35 {product} uintx TLABRefillWasteFraction = 64 {product} uintx TLABSize = 0 {product} bool TLABStats = true {product} uintx TLABWasteIncrement = 4 {product} uintx TLABWasteTargetPercent = 1 {product} bool TaggedStackInterpreter = false {product} intx TargetPLABWastePct = 10 {product} intx TargetSurvivorRatio = 50 {product} uintx TenuredGenerationSizeIncrement = 20 {product} uintx TenuredGenerationSizeSupplement = 80 {product} uintx TenuredGenerationSizeSupplementDecay = 2 {product} intx ThreadPriorityPolicy = 0 {product} bool ThreadPriorityVerbose = false {product} uintx ThreadSafetyMargin = 52428800 {product} intx ThreadStackSize = 0 {pd product} uintx ThresholdTolerance = 10 {product} intx Tier1BytecodeLimit = 10 {product} bool Tier1OptimizeVirtualCallProfiling = true {C1 product} bool Tier1ProfileBranches = true {C1 product} bool Tier1ProfileCalls = true {C1 product} bool Tier1ProfileCheckcasts = true {C1 product} bool Tier1ProfileInlinedCalls = true {C1 product} bool Tier1ProfileVirtualCalls = true {C1 product} bool Tier1UpdateMethodData = false {product} intx Tier2BackEdgeThreshold = 100000 {pd product} intx Tier2CompileThreshold = 1500 {pd product} intx Tier3BackEdgeThreshold = 100000 {pd product} intx Tier3CompileThreshold = 2500 {pd product} intx Tier4BackEdgeThreshold = 100000 {pd product} intx Tier4CompileThreshold = 4500 {pd product} bool TieredCompilation = false {pd product} bool TimeLinearScan = false {C1 product} bool TraceBiasedLocking = false {product} bool TraceClassLoading = false {product rw} bool TraceClassLoadingPreorder = false {product} bool TraceClassResolution = false {product} bool TraceClassUnloading = false {product rw} bool TraceGen0Time = false {product} bool TraceGen1Time = false {product} ccstr TraceJVMTI = {product} bool TraceLoaderConstraints = false {product rw} bool TraceMonitorInflation = false {product} bool TraceParallelOldGCTasks = false {product} intx TraceRedefineClasses = 0 {product} bool TraceSafepointCleanupTime = false {product} bool TraceSuspendWaitFailures = false {product} intx TypeProfileMajorReceiverPercent = 90 {product} intx TypeProfileWidth = 2 {product} intx UnguardOnExecutionViolation = 0 {product} bool Use486InstrsOnly = false {product} bool UseAdaptiveGCBoundary = false {product} bool UseAdaptiveGenerationSizePolicyAtMajorCollection = true {p bool UseAdaptiveGenerationSizePolicyAtMinorCollection = true {p bool UseAdaptiveNUMAChunkSizing = true {product} bool UseAdaptiveSizeDecayMajorGCCost = true {product} bool UseAdaptiveSizePolicy = true {product} bool UseAdaptiveSizePolicyFootprintGoal = true {product} bool UseAdaptiveSizePolicyWithSystemGC = false {product} bool UseAddressNop = false {product} bool UseAltSigs = false {product} bool UseAutoGCSelectPolicy = false {product} bool UseBiasedLocking = true {product} bool UseBoundThreads = true {product} bool UseCMSBestFit = true {product} bool UseCMSCollectionPassing = true {product} bool UseCMSCompactAtFullCollection = true {product} bool UseCMSInitiatingOccupancyOnly = false {product} bool UseCodeCacheFlushing = false {product} bool UseCompiler = true {product} bool UseCompilerSafepoints = true {product} bool UseConcMarkSweepGC = false {product} bool UseCountLeadingZerosInstruction = false {product} bool UseCounterDecay = true {product} bool UseDepthFirstScavengeOrder = true {product} bool UseFastAccessorMethods = true {product} bool UseFastEmptyMethods = true {product} bool UseFastJNIAccessors = true {product} bool UseG1GC = false {product} bool UseGCOverheadLimit = true {product} bool UseGCTaskAffinity = false {product} bool UseHeavyMonitors = false {product} bool UseInlineCaches = true {product} bool UseInterpreter = true {product} bool UseLWPSynchronization = true {product} bool UseLargePages = false {pd product} bool UseLargePagesIndividualAllocation := false {pd product} bool UseLoopCounter = true {product} bool UseMaximumCompactionOnSystemGC = true {product} bool UseMembar = false {product} bool UseNUMA = false {product} bool UseNewFeature1 = false {C1 product} bool UseNewFeature2 = false {C1 product} bool UseNewFeature3 = false {C1 product} bool UseNewFeature4 = false {C1 product} bool UseNewLongLShift = false {product} bool UseNiagaraInstrs = false {product} bool UseOSErrorReporting = false {pd product} bool UseOnStackReplacement = true {pd product} bool UsePSAdaptiveSurvivorSizePolicy = true {product} bool UseParNewGC = false {product} bool UseParallelDensePrefixUpdate = true {product} bool UseParallelGC = false {product} bool UseParallelOldGC = false {product} bool UseParallelOldGCCompacting = true {product} bool UseParallelOldGCDensePrefix = true {product} bool UsePerfData = true {product} bool UsePopCountInstruction = false {product} intx UseSSE = 99 {product} bool UseSSE42Intrinsics = false {product} bool UseSerialGC = false {product} bool UseSharedSpaces = true {product} bool UseSignalChaining = true {product} bool UseSpinning = false {product} bool UseSplitVerifier = true {product} bool UseStoreImmI16 = true {product} bool UseStringCache = false {product} bool UseTLAB = true {pd product} bool UseThreadPriorities = true {pd product} bool UseTypeProfile = true {product} bool UseUTCFileTimestamp = true {product} bool UseUnalignedLoadStores = false {product} bool UseVMInterruptibleIO = true {product} bool UseVectoredExceptions = false {pd product} bool UseXMMForArrayCopy = false {product} bool UseXmmI2D = false {product} bool UseXmmI2F = false {product} bool UseXmmLoadAndClearUpper = true {product} bool UseXmmRegToRegMoveAll = false {product} bool VMThreadHintNoPreempt = false {product} intx VMThreadPriority = -1 {product} intx VMThreadStackSize = 0 {pd product} intx ValueMapInitialSize = 11 {C1 product} intx ValueMapMaxLoopSize = 8 {C1 product} bool VerifyMergedCPBytecodes = true {product} intx WorkAroundNPTLTimedWaitHang = 1 {product} uintx YoungGenerationSizeIncrement = 20 {product} uintx YoungGenerationSizeSupplement = 80 {product} uintx YoungGenerationSizeSupplementDecay = 8 {product} uintx YoungPLABSize = 4096 {product} bool ZeroTLAB = false {product} intx hashCode = 0 {product}
以上這篇老生常談JVM的內(nèi)存溢出說明及參數(shù)調(diào)整就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。