Java 虛擬機(jī)所管理的內(nèi)存包括以下幾個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)域
一想虎、程序計(jì)數(shù)器
特點(diǎn):
- 線程私有
- 當(dāng)前線程的行號(hào)指示器
- 唯一一個(gè)在Java 虛擬機(jī)規(guī)范中沒有規(guī)定任何OOM情況的區(qū)域
二扫茅、Java 虛擬機(jī)棧
特點(diǎn):
- 線程私有
- 存放各種基本數(shù)據(jù)類型(boolean瓷患、byte未玻、char孽椰、short旨剥、int炭玫、float卵凑、long庆聘、double)、對(duì)象引用(reference類型)
- 使用-Xss 參數(shù)減少棧內(nèi)存容量
異常:
- 如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度勺卢,將拋出 StackOverflowError異常
- 如果虛擬機(jī)可以動(dòng)態(tài)擴(kuò)展伙判,如果擴(kuò)展時(shí)無法申請(qǐng)到足夠的內(nèi)存,就會(huì)報(bào)拋出OutOfMemoryError異常
三黑忱、本地方法棧
特點(diǎn):
- 線程私有
- 與虛擬機(jī)棧非常相似宴抚,虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法服務(wù),本地方法棧則為虛擬機(jī)使用Native 方法服務(wù)甫煞。
異常:
- 與虛擬機(jī)棧一樣菇曲,也會(huì)拋出 StackOverflowError 和 OutOfMemoryError 異常。
四抚吠、Java 堆
特點(diǎn):
- 線程共享
- 存放對(duì)象實(shí)例
- Java 堆是垃圾收集器管理的主要區(qū)域常潮,因此很多時(shí)候也被稱為“GC 堆”
- 從內(nèi)存回收角度來,由于現(xiàn)在收集器基本都采用分代收集算法楷力,所以Java 堆中還可以細(xì)分為:新生代和老年代喊式;再細(xì)致一點(diǎn)的有Eden 空間孵户、From Survivor空間、To Survivor 空間等岔留。
- 從內(nèi)存分配角度來看夏哭,線程共享的Java 堆中可能劃分出多個(gè)線程私有的分配緩沖區(qū)(Thread Local Allocation Buffer,TLAB)。
- Java 堆可以處于物理上不連續(xù)的內(nèi)存空間中献联,只要邏輯上是連續(xù)的即可竖配。
- 在實(shí)現(xiàn)時(shí),既可以實(shí)現(xiàn)成固定大小的里逆,也可以是可擴(kuò)展的(通過 -Xmx 和 -Xms 控制)
- 新生代和老年代內(nèi)存比例默認(rèn)為 1 : 2
- 新生代中內(nèi)存比例默認(rèn)為 Eden : From : To = 8 : 1 : 1
堆內(nèi)存參數(shù)調(diào)整:
- java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
- -Xmx3550m:設(shè)置JVM最大可用內(nèi)存為3550M进胯。
- -Xms3550m:設(shè)置JVM促使內(nèi)存為3550m。此值可以設(shè)置與-Xmx相同运悲,以避免每次垃圾回收完成后JVM重新分配內(nèi)存龄减。
- -Xmn2g:設(shè)置年輕代大小為2G。整個(gè)JVM內(nèi)存大小=年輕代大小 + 年老代大小 + 持久代大小班眯。持久代一般固定大小為64m,所以增大年輕代后烁巫,將會(huì)減小年老代大小署隘。此值對(duì)系統(tǒng)性能影響較大,Sun官方推薦配置為整個(gè)堆的3/8亚隙。
- -Xss128k:設(shè)置每個(gè)線程的堆棧大小磁餐。JDK5.0以后每個(gè)線程堆棧大小為1M,以前每個(gè)線程堆棧大小為256K阿弃。更具應(yīng)用的線程所需內(nèi)存大小進(jìn)行調(diào)整诊霹。在相同物理內(nèi)存下,減小這個(gè)值能生成更多的線程渣淳。但是操作系統(tǒng)對(duì)一個(gè)進(jìn)程內(nèi)的線程數(shù)還是有限制的脾还,不能無限生成,經(jīng)驗(yàn)值在3000~5000左右入愧。
- java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
- -XX:NewRatio=4:設(shè)置年輕代(包括Eden和兩個(gè)Survivor區(qū))與年老代的比值(除去持久代)鄙漏。設(shè)置為4,則年輕代與年老代所占比值為1:4棺蛛,年輕代占整個(gè)堆棧的1/5
- -XX:SurvivorRatio=4:設(shè)置年輕代中Eden區(qū)與Survivor區(qū)的大小比值怔蚌。設(shè)置為4,則兩個(gè)Survivor區(qū)與一個(gè)Eden區(qū)的比值為2:4旁赊,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/6
- -XX:MaxPermSize=16m:設(shè)置持久代大小為16m桦踊。
- -XX:MaxTenuringThreshold=0:設(shè)置垃圾最大年齡。如果設(shè)置為0的話终畅,則年輕代對(duì)象不經(jīng)過Survivor區(qū)籍胯,直接進(jìn)入年老代鳄橘。對(duì)于年老代比較多的應(yīng)用,可以提高效率芒炼。如果將此值設(shè)置為一個(gè)較大值瘫怜,則年輕代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制,這樣可以增加對(duì)象再年輕代的存活時(shí)間本刽,增加在年輕代即被回收的概論鲸湃。
異常:
- 如果在堆中沒有內(nèi)存完成實(shí)例分配,并且堆也無法再擴(kuò)展時(shí)子寓,將會(huì)拋出OutOfMemoryError 異常
五暗挑、方法區(qū)
特點(diǎn):
- 線程共享
- 存儲(chǔ)已被虛擬機(jī)加載的類信息、常量斜友、靜態(tài)變量炸裆、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
- jdk 1.8 后改為 Metapace 元數(shù)據(jù)區(qū)域
異常:
- 當(dāng)方法區(qū)無法滿足內(nèi)存分配需求時(shí)鲜屏,將拋出OutOfMemoryError 異常烹看。
六、運(yùn)行時(shí)常量池
特點(diǎn):
- 線程共享
- 是方法區(qū)的一部分
- Class 文件中除了有類的版本洛史、字段惯殊、方法、接口等描述信息外也殖、還有一項(xiàng)信息是常量池土思,用于存放編譯期生成的各種字面量和符號(hào)引用,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放
異常:
- 運(yùn)行時(shí)常量池是方法區(qū)的一部分忆嗜,受到方法區(qū)內(nèi)存的限制己儒,當(dāng)常量池?zé)o法再申請(qǐng)到內(nèi)存時(shí)會(huì)拋出 OutOfMemoryError 異常。