最近做畢設(shè)時 遇到了一點小問題 在解析dblp xml文件時(該文件很大 最新版本為 MB) 老是報錯
創(chuàng)新互聯(lián)建站專注于大通企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。大通網(wǎng)站建設(shè)公司,為大通等地區(qū)提供建站服務(wù)。全流程按需規(guī)劃網(wǎng)站,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)
java lang OutOfMemoryError: Java heap space
最后通過查資料才知道 這是由于JVM堆內(nèi)存不足造成的 JVM在啟動動的時候一般會設(shè)置JVM Heap的值
其初始空間(即 Xms)是物理內(nèi)存的 / 最大空間( Xmx)不可超過物理內(nèi)存 在JVM中如果 %的時間是用于GC 且可用的Heap size 不足 %的時候?qū)伋龃水惓P畔?出現(xiàn)這種問題可以通過修改JVM heap大小解決
如
點擊(此處)折疊或打開
java Xms M Xmx M className
以上設(shè)置JVM初始化堆內(nèi)存為 M 最大可用堆內(nèi)存為 M
( )在命令行中設(shè)置的方法就如上面所述
( )在Eclipse中可以這樣設(shè)置
在eclipse的 Run Run Configurations Arguments下的VM Arguments中設(shè)置
Xms M Xmx M
另外可以使用 java X查看其它JVM參數(shù)情況
點擊(此處)折疊或打開
D:\workjava X
Xmixed mixed mode execution (default)
Xint interpreted mode execution only
Xbootclasspath:directories and zip/jar files separated by ;
set search path for bootstrap classes and resources
Xbootclasspath/a:directories and zip/jar files separated by ;
append to end of bootstrap class path
Xbootclasspath/p:directories and zip/jar files separated by ;
prepend in front of bootstrap class path
Xnoclassgc disable class garbage collection
Xincgc enable incremental garbage collection
Xloggc:file log GC status to a file with time stamps
Xbatch disable background pilation
Xmssize set initial Java heap size
Xmxsize set maximum Java heap size
Xsssize set java thread stack size
Xprof output cpu profiling data
Xfuture enable strictest checks anticipating future default
Xrs reduce use of OS signals by Java/VM (see documentation)
Xcheck:jni perform additional checks for JNI functions
Xshare:off do not attempt to use shared class data
Xshare:auto use shared class data if possible (default)
Xshare:on require using shared class data otherwise fail
The X options are non standard and subject to change without notice
可以通過java lang Runtime的一些方法查看jvm的內(nèi)存使用情況
點擊(此處)折疊或打開
System out println( Total Memory: + Runtime getRuntime() totalMemory() / ( * + MB )
System out println( Free Memory: + Runtime getRuntime() freeMemory() / ( * ) + MB )
System out println( Max Memory: + Runtime getRuntime() maxMemory() / ( * ) + MB )
maxMemory()這個方法返回的是java虛擬機(jī)(這個進(jìn)程)能構(gòu)從操作系統(tǒng)那里挖到的最大的內(nèi)存 以字節(jié)為單位
totalMemory()這個方法返回的是java虛擬機(jī)現(xiàn)在已經(jīng)從操作系統(tǒng)那里挖過來的內(nèi)存大小 也就是java虛擬機(jī)這個進(jìn)程當(dāng)時所占用的所有內(nèi)存
freeMemory為當(dāng)前jvm中沒有使用的內(nèi)存
附 jvm參數(shù)說明 (轉(zhuǎn)自)
server:一定要作為第一個參數(shù) 在多個CPU時性能佳
Xms java Heap初始大小 默認(rèn)是物理內(nèi)存的 /
Xmx java heap最大值 建議均設(shè)為物理內(nèi)存的一半 不可超過物理內(nèi)存
XX:PermSize:設(shè)定內(nèi)存的永久保存區(qū)初始大小 缺省值為 M (我用visualvm exe查看的)
XX:MaxPermSize:設(shè)定內(nèi)存的永久保存區(qū)最大 大小 缺省值為 M (我用visualvm exe查看的)
XX:SurvivorRatio= ? :生還者池的大小 默認(rèn)是 如果垃圾回收變成了瓶頸 您可以嘗試定制生成池設(shè)置
XX:NewSize: 新生成的池的初始大小 缺省值為 M
XX:MaxNewSize: 新生成的池的最大大小 ?? 缺省值為 M
如果 JVM 的堆大小大于 GB 則應(yīng)該使用值 XX:newSize= m XX:MaxNewSize= m XX:SurvivorRatio= 或者將堆的總大小的 % 到 % 分配給新生成的池 調(diào)大新對象區(qū) 減少Full GC次數(shù)
+XX:AggressiveHeap 會使得 Xms沒有意義 這個參數(shù)讓jvm忽略Xmx參數(shù) 瘋狂地吃完一個G物理內(nèi)存 再吃盡一個G的swap
Xss 每個線程的Stack大小 Xss 這使得JBoss每增加一個線程(thread)就會立即消耗 M內(nèi)存 而最佳值應(yīng)該是 K 默認(rèn)值好像是 k
verbose:gc 現(xiàn)實垃圾收集信息
Xloggc:gc log 指定垃圾收集日志文件
Xmn young generation的heap大小 一般設(shè)置為Xmx的 分之一
XX:+UseParNewGC 縮短minor收集的時間
XX:+UseConcMarkSweepGC 縮短major收集的時間 此選項在Heap Size 比較大而且Major收集時間較長的情況下使用更合適
XX:userParNewGC 可用來設(shè)置并行收集【多CPU】
XX:ParallelGCThreads 可用來增加并行度【多CPU】
lishixinzhi/Article/program/Java/hx/201311/26103
不管是YGC還是Full GC,GC過程中都會對導(dǎo)致程序運行中中斷,正確的選擇不同的GC策略,調(diào)整JVM、GC的參數(shù),可以極大的減少由于GC工作,而導(dǎo)致的程序運行中斷方面的問題,進(jìn)而適當(dāng)?shù)奶岣逬ava程序的工作效率。但是調(diào)整GC是以個極為復(fù)雜的過程,由于各個程序具備不同的特點,如:web和GUI程序就有很大區(qū)別(Web可以適當(dāng)?shù)耐nD,但GUI停頓是客戶無法接受的),而且由于跑在各個機(jī)器上的配置不同(主要cup個數(shù),內(nèi)存不同),所以使用的GC種類也會不同(如何選擇見GC種類及如何選擇)。本文將注重介紹JVM、GC的一些重要參數(shù)的設(shè)置來提高系統(tǒng)的性能。
GC性能方面的考慮
對于GC的性能主要有2個方面的指標(biāo):吞吐量throughput(工作時間不算gc的時間占總的時間比)和暫停pause(gc發(fā)生時app對外顯示的無法響應(yīng))。
1. Total Heap
默認(rèn)情況下,vm會增加/減少heap大小以維持free space在整個vm中占的比例,這個比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。
一般而言,server端的app會有以下規(guī)則:
對vm分配盡可能多的memory;
將Xms和Xmx設(shè)為一樣的值。如果虛擬機(jī)啟動時設(shè)置使用的內(nèi)存比較小,這個時候又需要初始化很多對象,虛擬機(jī)就必須重復(fù)地增加內(nèi)存。
處理器核數(shù)增加,內(nèi)存也跟著增大。
2. The Young Generation
另外一個對于app流暢性運行影響的因素是young generation的大小。young generation越大,minor collection越少;但是在固定heap size情況下,更大的young generation就意味著小的tenured generation,就意味著更多的major collection(major collection會引發(fā)minor collection)。
NewRatio反映的是young和tenured generation的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,將這兩個值設(shè)為一樣就固定了young generation的大小(同Xms和Xmx設(shè)為一樣)。
如果希望,SurvivorRatio也可以優(yōu)化survivor的大小,不過這對于性能的影響不是很大。SurvivorRatio是eden和survior大小比例。
一般而言,server端的app會有以下規(guī)則:
首先決定能分配給vm的最大的heap size,然后設(shè)定最佳的young generation的大小;
如果heap size固定后,增加young generation的大小意味著減小tenured generation大小。讓tenured generation在任何時候夠大,能夠容納所有l(wèi)ive的data(留10%-20%的空余)。
經(jīng)驗規(guī)則
年輕代大小選擇
響應(yīng)時間優(yōu)先的應(yīng)用:盡可能設(shè)大,直到接近系統(tǒng)的最低響應(yīng)時間限制(根據(jù)實際情況選擇).在此種情況下,年輕代收集發(fā)生的頻率也是最小的.同時,減少到達(dá)年老代的對象.
吞吐量優(yōu)先的應(yīng)用:盡可能的設(shè)置大,可能到達(dá)Gbit的程度.因為對響應(yīng)時間沒有要求,垃圾收集可以并行進(jìn)行,一般適合8CPU以上的應(yīng)用.
避免設(shè)置過小.當(dāng)新生代設(shè)置過小時會導(dǎo)致:1.YGC次數(shù)更加頻繁 2.可能導(dǎo)致YGC對象直接進(jìn)入舊生代,如果此時舊生代滿了,會觸發(fā)FGC.
年老代大小選擇
響應(yīng)時間優(yōu)先的應(yīng)用:年老代使用并發(fā)收集器,所以其大小需要小心設(shè)置,一般要考慮并發(fā)會話率和會話持續(xù)時間等一些參數(shù).如果堆設(shè)置小了,可以會造成內(nèi)存碎 片,高回收頻率以及應(yīng)用暫停而使用傳統(tǒng)的標(biāo)記清除方式;如果堆大了,則需要較長的收集時間.最優(yōu)化的方案,一般需要參考以下數(shù)據(jù)獲得:
并發(fā)垃圾收集信息、持久代并發(fā)收集次數(shù)、傳統(tǒng)GC信息、花在年輕代和年老代回收上的時間比例。
吞吐量優(yōu)先的應(yīng)用:一般吞吐量優(yōu)先的應(yīng)用都有一個很大的年輕代和一個較小的年老代.原因是,這樣可以盡可能回收掉大部分短期對象,減少中期的對象,而年老代盡存放長期存活對象.
較小堆引起的碎片問題
因為年老代的并發(fā)收集器使用標(biāo)記,清除算法,所以不會對堆進(jìn)行壓縮.當(dāng)收集器回收時,他會把相鄰的空間進(jìn)行合并,這樣可以分配給較大的對象.但是,當(dāng)堆空間較小時,運行一段時間以后,就會出現(xiàn)"碎片",如果并發(fā)收集器找不到足夠的空間,那么并發(fā)收集器將會停止,然后使用傳統(tǒng)的標(biāo)記,清除方式進(jìn)行回收.如果出現(xiàn)"碎片",可能需要進(jìn)行如下配置:
-XX:+UseCMSCompactAtFullCollection:使用并發(fā)收集器時,開啟對年老代的壓縮.
-XX:CMSFullGCsBeforeCompaction=0:上面配置開啟的情況下,這里設(shè)置多少次Full GC后,對年老代進(jìn)行壓縮
用64位操作系統(tǒng),Linux下64位的jdk比32位jdk要慢一些,但是吃得內(nèi)存更多,吞吐量更大
XMX和XMS設(shè)置一樣大,MaxPermSize和MinPermSize設(shè)置一樣大,這樣可以減輕伸縮堆大小帶來的壓力
使用CMS的好處是用盡量少的新生代,經(jīng)驗值是128M-256M, 然后老生代利用CMS并行收集, 這樣能保證系統(tǒng)低延遲的吞吐效率。 實際上cms的收集停頓時間非常的短,2G的內(nèi)存, 大約20-80ms的應(yīng)用程序停頓時間
系統(tǒng)停頓的時候可能是GC的問題也可能是程序的問題,多用jmap和jstack查看,或者killall -3 java,然后查看java控制臺日志,能看出很多問題。(相關(guān)工具的使用方法將在后面的blog中介紹)
仔細(xì)了解自己的應(yīng)用,如果用了緩存,那么年老代應(yīng)該大一些,緩存的HashMap不應(yīng)該無限制長,建議采用LRU算法的Map做緩存,LRUMap的最大長度也要根據(jù)實際情況設(shè)定。
采用并發(fā)回收時,年輕代小一點,年老代要大,因為年老大用的是并發(fā)回收,即使時間長點也不會影響其他程序繼續(xù)運行,網(wǎng)站不會停頓
JVM參數(shù)的設(shè)置(特別是 –Xmx –Xms –Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold等參數(shù)的設(shè)置沒有一個固定的公式,需要根據(jù)PV old區(qū)實際數(shù)據(jù) YGC次數(shù)等多方面來衡量。為了避免promotion faild可能會導(dǎo)致xmn設(shè)置偏小,也意味著YGC的次數(shù)會增多,處理并發(fā)訪問的能力下降等問題。每個參數(shù)的調(diào)整都需要經(jīng)過詳細(xì)的性能測試,才能找到特定應(yīng)用的最佳配置。
promotion failed:
垃圾回收時promotion failed是個很頭痛的問題,一般可能是兩種原因產(chǎn)生,第一個原因是救助空間不夠,救助空間里的對象還不應(yīng)該被移動到年老代,但年輕代又有很多對象需要放入救助空間;第二個原因是年老代沒有足夠的空間接納來自年輕代的對象;這兩種情況都會轉(zhuǎn)向Full GC,網(wǎng)站停頓時間較長。
解決方方案一:
第一個原因我的最終解決辦法是去掉救助空間,設(shè)置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可,第二個原因我的解決辦法是設(shè)置CMSInitiatingOccupancyFraction為某個值(假設(shè)70),這樣年老代空間到70%時就開始執(zhí)行CMS,年老代有足夠的空間接納來自年輕代的對象。
解決方案一的改進(jìn)方案:
又有改進(jìn)了,上面方法不太好,因為沒有用到救助空間,所以年老代容易滿,CMS執(zhí)行會比較頻繁。我改善了一下,還是用救助空間,但是把救助空間加大,這樣也不會有promotion failed。具體操作上,32位Linux和64位Linux好像不一樣,64位系統(tǒng)似乎只要配置MaxTenuringThreshold參數(shù),CMS還是有暫停。為了解決暫停問題和promotion failed問題,最后我設(shè)置-XX:SurvivorRatio=1 ,并把MaxTenuringThreshold去掉,這樣即沒有暫停又不會有promotoin failed,而且更重要的是,年老代和永久代上升非常慢(因為好多對象到不了年老代就被回收了),所以CMS執(zhí)行頻率非常低,好幾個小時才執(zhí)行一次,這樣,服務(wù)器都不用重啟了。
-Xmx4000M -Xms4000M -Xmn600M -XX:PermSize=500M -XX:MaxPermSize=500M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log
CMSInitiatingOccupancyFraction值與Xmn的關(guān)系公式
上面介紹了promontion faild產(chǎn)生的原因是EDEN空間不足的情況下將EDEN與From survivor中的存活對象存入To survivor區(qū)時,To survivor區(qū)的空間不足,再次晉升到old gen區(qū),而old gen區(qū)內(nèi)存也不夠的情況下產(chǎn)生了promontion faild從而導(dǎo)致full gc.那可以推斷出:eden+from survivor old gen區(qū)剩余內(nèi)存時,不會出現(xiàn)promontion faild的情況,即:
(Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)=(Xmn-Xmn/(SurvivorRatior+2)) 進(jìn)而推斷出:
CMSInitiatingOccupancyFraction =((Xmx-Xmn)-(Xmn-Xmn/(SurvivorRatior+2)))/(Xmx-Xmn)*100
例如:
當(dāng)xmx=128 xmn=36 SurvivorRatior=1時 CMSInitiatingOccupancyFraction=((128.0-36)-(36-36/(1+2)))/(128-36)*100 =73.913
當(dāng)xmx=128 xmn=24 SurvivorRatior=1時 CMSInitiatingOccupancyFraction=((128.0-24)-(24-24/(1+2)))/(128-24)*100=84.615…
當(dāng)xmx=3000 xmn=600 SurvivorRatior=1時 CMSInitiatingOccupancyFraction=((3000.0-600)-(600-600/(1+2)))/(3000-600)*100=83.33
CMSInitiatingOccupancyFraction低于70% 需要調(diào)整xmn或SurvivorRatior值。
設(shè)置Java虛擬機(jī)JVM啟動內(nèi)存參數(shù)方法如下:
Tomcat修改TOMCAT_HOME/bin/catalina.bat,在[echo Using CATALINA_BASE: "%CATALINA_BASE%"] 上面加入,比如:
set JAVA_OPTS= -server -Xms1536m -Xmx1536m或者JAVA_OPTS="-server -Xms1536m -Xmx1536m",
服務(wù)器模式參數(shù)-server不加也可以 ,就變成
set JAVA_OPTS= -Xms1536m -Xmx1536m或者JAVA_OPTS=" -Xms1536m -Xmx1536m",
本文題目:java代碼設(shè)置jvm java代碼設(shè)置陷阱
本文路徑:http://www.chinadenli.net/article2/dddseic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、靜態(tài)網(wǎng)站、網(wǎng)站排名、App開發(fā)、外貿(mào)網(wǎng)站建設(shè)、App設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)