1.虛擬機(jī):(當(dāng)前最廣泛的是HotSpot虛擬機(jī))
? ?a.系統(tǒng)虛擬機(jī)(Vmware和Vitual Box)
? ?b.程序虛擬機(jī)(阿里云等)
2.jvm主要組成:
3..堆伤锚、棧有序、方法區(qū):
? ? 堆:解決數(shù)據(jù)存儲(chǔ)的問題(如何存放.放在哪里)?自動(dòng)化管理,通過垃圾回收機(jī)制,
? ? ? ? ?垃圾對(duì)象會(huì)自動(dòng)清理,不需要顯示釋放
? ? ? ? ?新生代:新產(chǎn)生不久的對(duì)象
? ? ? ? ? ? ? ? ? ?eden(伊甸園):剛new的對(duì)象存放到eden,被垃圾回收一次后進(jìn)入s0或s1
? ? ? ? ? ? ? ? ? ?s0(from):存放第一次垃圾回收后存活的對(duì)象(s0有對(duì)象時(shí),s1則不能有)(gc完還存活,會(huì)直接將s0復(fù)制到s1,即復(fù)制算法)
? ? ? ? ? ? ? ? ? ?s1(to):同理s0
? ? ? ? ? ? ? ? ? ?大小s0==s1,并且可相互轉(zhuǎn)換角色??
? ? ? ? ?老年代(tenured):存放產(chǎn)生比較久(垃圾回收多次)的對(duì)象 ? ?
? ? 棧:解決程序的運(yùn)行問題,(程序如何執(zhí)行,數(shù)據(jù)如何處理)線程私有的內(nèi)存空間:
? ? ? ? ?局部變量表:用于報(bào)錯(cuò)函數(shù)的參數(shù)及局部變量
? ? ? ? ?操作數(shù)棧:存儲(chǔ)計(jì)算過程的中間結(jié)果,作為變量的臨時(shí)存儲(chǔ)空間
? ? ? ? ?幀數(shù)據(jù)區(qū)(類似局部變量表):保存訪問常量池的指針单匣,存儲(chǔ)函數(shù)返回或出現(xiàn)異常的異常處理表
方法區(qū):輔助堆棧的一塊永久區(qū)(Perm)团南,解決堆棧信息的產(chǎn)生,類的數(shù)量和靜態(tài)常量的數(shù)量過多,則會(huì)導(dǎo)致內(nèi)存溢出(則需要增加方法區(qū)大小)
? ? ? ? ? ?User user=new User() :User類的模版信息宗雇、靜態(tài)信息都存在方法區(qū)中
? ? ? ? ? ?user存在于棧中,user指向的實(shí)例存在于堆中
4.虛擬機(jī)參數(shù):對(duì)系統(tǒng)調(diào)試和問題排查有幫助
? ?-XX:對(duì)于系統(tǒng)級(jí)別(jvm)的配置,打印log級(jí)別等的信息钳恕、jvm使用什么樣的垃圾回收器
? ?非-XX:基本都是對(duì)應(yīng)用層面上的配置
? ?+:?jiǎn)⒂?? -:禁用
? ?-XX:+PrintGc:虛擬機(jī)啟動(dòng)后,只要遇到GC就會(huì)打印日志
? ?-XX:+UseSerialGC 配置串行回收器
? ?-XX:PrintGCDetails 可查看詳細(xì)信息,包括各個(gè)區(qū)的情況
? ?-Xms: 設(shè)置Java程序啟動(dòng)時(shí)初始堆大小
? ?-Xmx: 設(shè)置Java程序能獲得的最大堆大小
-Xms20m -Xmx20m -XX:+PrintCommandLineFlags(類似showversion):可將隱式或顯示傳給虛擬機(jī)的參數(shù)輸出
-XX:+PrintCommandLineFlags可以讓在程序運(yùn)行前打印出用戶手動(dòng)設(shè)置或者JVM自動(dòng)設(shè)置的XX選項(xiàng)别伏,加上這個(gè)選項(xiàng)可以輔助問題診斷。
一般在工作中,會(huì)將初始堆的大小與最大堆大小設(shè)置相等,原因是可減少程序運(yùn)行時(shí)的垃圾回收次數(shù),從而提高性能
jdk1.8將perm改為Metaspace
5.參數(shù)配置
? ?-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 ?-XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
初始20M ? 最大20M ? 新生代1ms0/s1和eden區(qū)比例?GC時(shí)打印信息 ? ? ? 串行回收器
-Xmn:一般設(shè)置較大的新生代(堆的1/4到1/3之間)減少老年代的大小,
XX:SurvivorRatio=2 ?設(shè)置eden和from/to的比例
-Xms20m -Xmx20m?-XX:NewRatio=2?-XX:+PrintGCDetails -XX:+UseSerialGC
-XX:NewRatio=2 ?老年代與新生代比例為2:1
?經(jīng)驗(yàn):不同的堆分布情況,會(huì)對(duì)系統(tǒng)執(zhí)行產(chǎn)生一定影響,實(shí)際配置中,應(yīng)根據(jù)系統(tǒng)的特點(diǎn)做出合力的配置,
? ? ?策略:1.盡可能將對(duì)象預(yù)留在新生代,減少老年代的GC次數(shù)(耗性能)
? ? ? ? ? ? ? 2.設(shè)置新生代的絕對(duì)大小(-Xmn)
? ? ? ? ? ? ? 3.設(shè)置新生代和老年代的比例: -XX:NewRatio=老年代/新生代
6.內(nèi)存溢出(OOM)-XX:+HeapDumpOnOutOfMemrorError?-XX:HeapDumpPath 可設(shè)置導(dǎo)出堆信息的存放路徑
? ??參考連接:http://blog.csdn.net/jia20003/article/details/50703944??
? ?推薦:virtual vm ? 或Jconsole
? ?內(nèi)存分析工具:MemoryAnalyzer1.5
eclipse下載地址:http://download.eclipse.org/mat/1.5/update-site/
? ?jdk1.8配置臨界值(低于25M就會(huì)報(bào)錯(cuò)):
? ? -Xms25m -Xmx25m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:/testDir/error.dump
7.-Xss指定線程的最大椨嵌睿空間,直接決定函數(shù)可調(diào)用的最大深度(常見遞歸,StackOverFolw)
? ? 方法區(qū)(永久區(qū)):是一塊所有線程共享的內(nèi)存區(qū)域,用于保存系統(tǒng)的類信息,默認(rèn)值:-XX:MaxPermSize為64M ?
? ? 當(dāng)系統(tǒng)的類相當(dāng)多時(shí),需要設(shè)置合適的方法區(qū),以免出現(xiàn)永久區(qū)內(nèi)存溢出,
? ? -XX:PermSize=64M ?-XX:MaxPermSize=64M
8.目前Jvm支持Client和Server兩種模式,1.7之后為Server模式
? -client可指定使用Client模式 (不追求系統(tǒng)長(zhǎng)時(shí)間使用性能僅僅是測(cè)試時(shí)推薦)?
? -server使用server模式(啟動(dòng)較慢,原因是會(huì)對(duì)其進(jìn)行復(fù)雜的系統(tǒng)性能信息收集和使用更復(fù)雜的算法對(duì)程序進(jìn)行優(yōu)化) ?
? 一般生產(chǎn)環(huán)境都會(huì)Server模式(長(zhǎng)期運(yùn)行性能遠(yuǎn)快于Client模式) ,java -version即可查看何種模式
9.垃圾回收(GC):清理存于內(nèi)存中畸肆、不會(huì)再被使用的對(duì)象
? ?常見算法:引用計(jì)數(shù)法、標(biāo)記壓縮法宙址、復(fù)制算法轴脐、分代、分區(qū)
10.引用計(jì)數(shù)法(經(jīng)典):在對(duì)象被其他引用時(shí)計(jì)數(shù)器加1,當(dāng)引用失敗時(shí)減1,缺點(diǎn):a.無法處理循環(huán)引用的情況(如遞歸等) b.進(jìn)行加減操作比較浪費(fèi)系統(tǒng)性能
?標(biāo)記清除法:分為標(biāo)記和清除兩個(gè)階段進(jìn)行處理內(nèi)存中的對(duì)象抡砂,但是容易導(dǎo)致內(nèi)存碎片問題大咱,垃圾回收后的空間不連續(xù),導(dǎo)致其工作效率低于連續(xù)的工作空間
?復(fù)制算法:將內(nèi)存空間分為兩塊,每次只使用其中一塊注益,在垃圾回收時(shí)碴巾,將正在使用的內(nèi)存中存留對(duì)象復(fù)制到未被使用的內(nèi)存塊中去,之后清除之前正在使用的內(nèi)存塊中所有的對(duì)象丑搔,反復(fù)交換兩個(gè)內(nèi)存的角色厦瓢,完成回收。(新生代的from和to空間就使用此算法)
?標(biāo)記壓縮法:基于標(biāo)記清除法之上做的優(yōu)化啤月,把存活的對(duì)象壓縮到內(nèi)存的一端煮仇,再進(jìn)行垃圾清理(老年代使用此算法)
?分代算法:根據(jù)對(duì)象的特點(diǎn)把內(nèi)存分成N塊,根據(jù)每個(gè)內(nèi)存的特點(diǎn)使用不同的算法。對(duì)于新生代回收頻率高谎仲,耗時(shí)短和老年代回收頻率低浙垫、耗時(shí)長(zhǎng)的特點(diǎn),贏盡量減少老年代的GC
?分區(qū)算法:將整個(gè)內(nèi)存分為N個(gè)小的獨(dú)立空間,然后細(xì)粒度的控制單次回收部分小空間夹姥,而非對(duì)整個(gè)空間的GC杉武, ?從而提高性能,減少GC的停頓時(shí)間
11.垃圾回收時(shí)的停頓現(xiàn)象:垃圾回收器的任務(wù)是識(shí)別和回收垃圾對(duì)象進(jìn)行內(nèi)存清理辙售,為了讓垃圾回收器可以高效執(zhí)行轻抱,大部分情況下,系統(tǒng)會(huì)進(jìn)入一個(gè)停頓的狀態(tài)(終止所有的應(yīng)用線程,以避免不會(huì)有新的垃圾產(chǎn)生,同時(shí)確保系統(tǒng)狀態(tài)在該瞬間下的一致性,也有利于更好的標(biāo)記垃圾對(duì)象)
12.對(duì)象進(jìn)入老年代的條件:一般對(duì)象首次創(chuàng)建會(huì)被放置在新生代的eden區(qū),如果沒有GC介入,則對(duì)象不會(huì)離開eden區(qū)旦部;一般而言十拣,只要對(duì)象的年齡(GC次數(shù)決定,新生代每次GC后沒有被回收則年齡加1)達(dá)到一定的大小,就會(huì)自動(dòng)進(jìn)入老年代志鹃,-XX:MaxTenuringThreshold?控制新生代對(duì)象的最大年齡(即多少次GC后進(jìn)入老年代)夭问,默認(rèn)為15
此外,大對(duì)象(新生代eden區(qū)無法裝入時(shí),也會(huì)直接進(jìn)入老年代)曹铃,-XX:PretenureSizeThreshold?設(shè)置對(duì)象晉升為老年代的大小缰趋,但要注意TLAB區(qū)域優(yōu)先分配空間
13.TLAB(Thread Local Allocation Buffer)區(qū):線程本地分配緩存,線程專用的內(nèi)存分配區(qū)域,為了加速對(duì)象分配而生。每個(gè)線程都會(huì)有一個(gè)獨(dú)享的TLAB工作區(qū)域,Jvm通過TLAB區(qū)來避免多線程沖突問題陕见,提高對(duì)象分配的效率秘血。TLAB 一般不會(huì)太大,當(dāng)對(duì)象無法在TLAB分配時(shí),則會(huì)直接分配到堆上。
?-XX:+UseTLAB?使用TLAB?-XX:TLABSize?設(shè)置TLAB大小
?-XX:TLABRefillWasterFraction?設(shè)置維護(hù)進(jìn)入TLAB空間的單個(gè)對(duì)象大小(比例值,默認(rèn)64,即如果對(duì)象大于整個(gè)空間的1/64,則在堆創(chuàng)建對(duì)象)
-XX:+PrintTLAB?打印TLAB信息
-XX:ResizeTLAB?自動(dòng)調(diào)整TLABRefillWasterFraction閾值
-XX:-DoEscapeAnalysis -server?禁用掉,能打印TLAB(線程內(nèi)核級(jí)別)信息
14.對(duì)象創(chuàng)建的基本流程:根據(jù)數(shù)據(jù)的大小,參數(shù)的設(shè)置,決定如何創(chuàng)建分配,以及分配的位置