2、:?分配內(nèi)存?保證所有正在被引用的對(duì)象還存在于內(nèi)存中?I叫收?qǐng)?zhí)行代碼已經(jīng)不再引用的對(duì)象所占的內(nèi)存應(yīng)用執(zhí)行時(shí),定位和回收垃圾對(duì)彖的過(guò)程會(huì)山用總執(zhí)行時(shí)間的將近25%,這會(huì)拖累應(yīng)用的執(zhí)行效率。HotspotVM提供的垃圾回收器是一個(gè)分代垃圾回收器(GenerationalGC)[9,16,18]-將內(nèi)存劃分為不同的階段,也就是說(shuō),不同的生命周期的對(duì)象放置在不同的地址池中。這樣的設(shè)計(jì)是基于弱年代假設(shè)(WeakGenerationalHypothesis):1?越早分配的對(duì)彖越容易失效;2.老對(duì)象很少會(huì)引用新對(duì)象。這種分代方式可以減少垃圾回收的停頓時(shí)間以及大范圍對(duì)象
3、的回收成木。HotspotVM將一其堆空間分為三個(gè)分代空間:1.年輕代(YoungGeneration)O????Java應(yīng)用在分配Java對(duì)象時(shí),這些對(duì)象會(huì)被分配到年輕代堆空間中去O????這個(gè)空間人多是小對(duì)象并11會(huì)被頻繁回收O????曲于年輕代堆空間的垃圾回收會(huì)很頻繁,因此其垃圾回收算法會(huì)更加重視回收效率2.年老代(OldGenerationn)O????年輕代堆空間的長(zhǎng)期存活對(duì)彖會(huì)轉(zhuǎn)移到(也許是永久性轉(zhuǎn)移)年老代堆空間O????這個(gè)堆空間通常比年輕代的堆空間人,并11其空間增長(zhǎng)速度較緩O????由于大部分JVM堆空間都分配給了年老代,因此其垃圾回收
4、算法需要更節(jié)省空間,此算法需要能夠處理低垃圾密度的堆空間3.持久代(PermanentGeneration)O????存放VM和Java類的元數(shù)據(jù)(metadata),以及interned字符串和類的靜態(tài)變量次收集(MinorGC)和全收集(FullGC)當(dāng)這三個(gè)分代的堆空間比較緊張或者沒(méi)有足夠的空間來(lái)為新到的請(qǐng)求分配的時(shí)候,垃圾冋收機(jī)制就會(huì)起作用。有兩種類型的垃圾冋收方式:次收集和全收集。當(dāng)年輕代堆空間滿了的時(shí)候,會(huì)觸發(fā)次收集將還存活的對(duì)象移到年老代堆空間。當(dāng)年老代堆空間滿了的時(shí)候,會(huì)觸發(fā)一個(gè)覆蓋全范圍的對(duì)象堆的全收集。次收集?當(dāng)年輕代堆空間緊張時(shí)會(huì)被觸
5、發(fā)?相對(duì)于全收集而言,收集間隔較短全收集?當(dāng)老年代或者持久代堆空間滿了,會(huì)觸發(fā)全收集操作?可以使用Systcm.gc()方法來(lái)顯式的啟動(dòng)全收集?全收集一般根據(jù)堆大小的不同,需耍的吋間不盡相同,但一般會(huì)比較長(zhǎng)。不過(guò),如果全收集時(shí)間超過(guò)3到5秒鐘,那就太長(zhǎng)了[1]全收集通常時(shí)間最長(zhǎng),并且是程序無(wú)法延遲執(zhí)行或者無(wú)法達(dá)到吞吐量目標(biāo)的主因。GC的目標(biāo)是去減少程序運(yùn)行過(guò)程中垃圾回收的頻率。為了達(dá)到這個(gè)目的,可以從這兩方而入手:?從系統(tǒng)方面考慮:O???盡量采用大堆,但是不要大到需耍系統(tǒng)從磁盤上“換”頁(yè)。一般而言,可用的RAM(沒(méi)有被系統(tǒng)進(jìn)程占用的)的80%都應(yīng)該分配給
6、JVMoO???Java堆空間越大,垃圾回收器和jav且應(yīng)用在喬吐量(throughput}和延遲執(zhí)行(latency)方而的效果越好。從應(yīng)用方血考慮:O???減少對(duì)象分配Jobjcctallocations'操作,或者采用對(duì)象保留(objectretention)方式冇助于減小存活的數(shù)據(jù)大小,這也可以反過(guò)來(lái)幫助垃圾回收做的更好。O???參考這篇文章一Java性能提升竅門[19]內(nèi)存溢出錯(cuò)誤(OutOfMemoryError)可怕的內(nèi)存溢出錯(cuò)誤是Java程序員最不愿意看到的。然而這個(gè)錯(cuò)誤還是會(huì)出現(xiàn),尤其應(yīng)用中涉及到大量的數(shù)據(jù)處理時(shí),或應(yīng)用運(yùn)行時(shí)間過(guò)長(zhǎng)時(shí)。一
7、個(gè)應(yīng)用所占內(nèi)存大小包括:?Java堆人小?線程棧?I/O緩沖區(qū)?原生庫(kù)所分配的內(nèi)存當(dāng)一個(gè)應(yīng)用耗盡了內(nèi)存并且JVMGC也無(wú)法回收任何對(duì)象空間的時(shí)候,就會(huì)發(fā)生內(nèi)存溢出錯(cuò)謀。但是,內(nèi)存溢出錯(cuò)謀并不一定就意味著內(nèi)存泄露(memoryleak)o也冇可能只是一個(gè)配置問(wèn)題,例如設(shè)置的堆大小(如果沒(méi)冇設(shè)置那就是缺省的堆大小)對(duì)于應(yīng)用來(lái)說(shuō)是不夠用的。JVM命令行參數(shù)無(wú)論是客戶端應(yīng)用還是服務(wù)器端應(yīng)用,一旦系統(tǒng)運(yùn)行緩慢并且垃圾回收所占時(shí)間過(guò)長(zhǎng),你就會(huì)希望通過(guò)調(diào)整堆大小來(lái)改善這一點(diǎn)。不過(guò),為了不影響其他也跑在同一個(gè)系統(tǒng)中的應(yīng)用,不應(yīng)該將堆大小設(shè)置的過(guò)大。GC調(diào)優(yōu)是很重要的。找到
8、最佳的分代堆空間是一個(gè)迭代的過(guò)程[3,10,12]o這里我們假定你