-Xms1024m:設置初始化內(nèi)存分配大小,默認為本地內(nèi)存的1/64。
-Xmx1024m:設置最大分配內(nèi)存,默認為本地內(nèi)存的1/4。
底層方法,與native方法相關(guān)。
線程私有,內(nèi)存連續(xù),存放8大基本類型+對象引用+實例的方法引用。
也叫PC寄存器,線程私有,保存當前執(zhí)行指令的地址。
線程共享,內(nèi)存不連續(xù),存放對象實例。
-XX:+HeapDumpOnOutOfMemoryError:OOM
方法區(qū)是一個JVM規(guī)范上的邏輯概念,實際的位置根據(jù)不同JVM來看。
hotspotJVM虛擬機上將堆中的永久代作為方法區(qū)的一個存儲實現(xiàn),為的是方法區(qū)也可以用堆內(nèi)存的GC垃圾回收機制,而不用重新針對方法區(qū)做GC操作,直接使用堆內(nèi)存的GC就可以了。
存放靜態(tài)變量(static)、常量(final)、類信息(Class,如構(gòu)造方法、接口定義)、常量池。實例變量存在堆內(nèi)存中,和方法區(qū)無關(guān)。
在Java7中永久代中存儲的部分數(shù)據(jù)已經(jīng)開始轉(zhuǎn)移到JavaHeap或NativeMemory中了。比如,符號引用(Symbols)轉(zhuǎn)移到了NativeMemory;字符串常量池(internedstrings)、類的靜態(tài)變量(classstatics)轉(zhuǎn)移到了JavaHeap,永久代中存放類和類加載器的元數(shù)據(jù)信息。
移除堆中的永久區(qū),用占用本地內(nèi)存的元空間(MetaSpace)來代替,存放類和類加載器的元數(shù)據(jù)信息。
符號引用沒有存在元空間中,而是繼續(xù)存在nativeheap中,這是兩個方式和位置,不過都可以算作是本地內(nèi)存,在虛擬機之外進行劃分,沒有設置限制參數(shù)時只受物理內(nèi)存大小限制,即只有占滿了操作系統(tǒng)可用內(nèi)存后才OOM。
-XX:MetaspaceSize來調(diào)整元空間初始大小,最大為本地內(nèi)存大小。
感謝您的閱讀,本文已同步到我的個人博客,您的關(guān)注是對我最大的鼓勵!
當然。
把JVM看成是個中間層就可以,不止是內(nèi)存分配,還有線程、網(wǎng)絡連接等等,最終在底層都要靠操作系統(tǒng)來搞。
Java語言的設計思想,本來就是對C語言這種可以直接進行操作系統(tǒng)調(diào)用的語言的一種簡化。引入了一個隔離層,讓jvm來當個中介,以簡化應用開發(fā)。讓程序員集中精力于實現(xiàn)業(yè)務邏輯。
JVM全稱JavaVirtualMachine,也就是我們耳熟能詳?shù)腏ava虛擬機。它能識別.class后綴的文件,并且能夠解析它的指令,最終調(diào)用操作系統(tǒng)上的函數(shù),完成我們想要的操作。
元空間大小參數(shù):
堆大小參數(shù):
-Xms:堆的最小值;
-Xmx:堆的最大值;
-Xmn:新生代的大小;
-XX:NewSize;新生代最小值;
-XX:MaxNewSize:新生代最大值;
例如-Xmx256m
功能
(1)運行時常量池溢出
(2)方法區(qū)中保存的Class對象沒有被及時回收掉或者Class信息占用的內(nèi)存超過了我們配置。
注意Class要被回收,條件比較苛刻(僅僅是可以,不代表必然,因為還有一些參數(shù)可以進行控制):
1、該類所有的實例都已經(jīng)被回收,也就是堆中不存在該類的任何實例。
2、加載該類的ClassLoader已經(jīng)被回收。
3、該類對應的java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。
()類裝載子系統(tǒng)
裝載連接初始化
()方法區(qū)被所有線程共享垃圾收集也會清理方法區(qū)中的無用類型對象
a類型信息類加載器加載類時從類文件中提取出來
類的完整有效名
父類的完整有效名(interfaceandjavalangObject除外因為無父類)
類型的修飾符
類型直接接口列表
b常量池存儲了一個類型所使用的常量所有類型域和方法的符號引用
c域信息jvm必須在方法區(qū)中保存類型的所有域的相關(guān)信息以及域的聲明順序
域的相關(guān)信息包括
域名
域類型
域修飾符(publicprivateprotectedstaticfinalvolatiletransient…)
d方法信息
方法名
方法返回類型
方法參數(shù)
方法的修飾符
方法的字節(jié)碼(abstractandnative除外)(被PC寄存器指向)
操作數(shù)棧和方法棧幀的局部變量區(qū)的大小
異常表
e類的靜態(tài)變量(所有對象共享一分拷貝)
f類的被聲明為final的類變量(所有對象共享一分拷貝)
g加載一個類的類加載器的引用
hClass類的引用
i方法表
j一個例子
ClassLava{
privateintspeed=;
voidflow();
}
ClassVolcano{
publicstaticvoidmain(String[]args){
Lavalava=newLava();
lavaflow();
}
}
下面我們描述一下main()方法的第一條指令的字節(jié)碼是如何被執(zhí)行的不同的jvm實現(xiàn)的差別很大這里只是其中之一
為了運行這個程序你以某種方式把Volcano傳給了jvm有了這個名字jvm找到了這個類文件(Volcanoclass)并讀入它從類文件提取了類型信息并放在了方法區(qū)中通過解析存在方法區(qū)中的字節(jié)碼jvm激活了main()方法在執(zhí)行時jvm保持了一個指向當前類(Volcano)常量池的指針
注意jvm在還沒有加載Lava類的時候就已經(jīng)開始執(zhí)行了正像大多數(shù)的jvm一樣不會等所有類都加載了以后才開始執(zhí)行它只會在需要的時候才加載
main()的第一條指令告知jvm為列在常量池第一項的類分配足夠的內(nèi)存
jvm使用指向Volcano常量池的指針找到第一項發(fā)現(xiàn)是一個對Lava類的符號引用然后它就檢查方法區(qū)看lava是否已經(jīng)被加載了
這個符號引用僅僅是類lava的完整有效名lava這里我們看到為了jvm能盡快從一個名稱找到一個類一個良好的數(shù)據(jù)結(jié)構(gòu)是多么重要這里jvm的實現(xiàn)者可以采用各種方法如hash表查找樹等等同樣的算法可以用于Class類的forName()的實現(xiàn)
當jvm發(fā)現(xiàn)還沒有加載過一個稱為Lava的類它就開始查找并加載類文件Lavaclass它從類文件中抽取類型信息并放在了方法區(qū)中
jvm于是以一個直接指向方法區(qū)lava類的指針替換了常量池第一項的符號引用以后就可以用這個指針快速的找到lava類了而這個替換過程稱為常量池解析(constantpoolresolution)在這里我們替換的是一個native指針
jvm終于開始為新的lava對象分配空間了這次jvm仍然需要方法區(qū)中的信息它使用指向lava數(shù)據(jù)的指針(剛才指向volcano常量池第一項的指針)找到一個lava對象究竟需要多少空間
一旦jvm知道了一個Lava對象所要的空間它就在堆上分配這個空間并把這個實例的變量speed初始化為缺省值假如lava的父對象也有實例變量則也會初始化
當把新生成的lava對象的引用壓到棧中第一條指令也結(jié)束了下面的指令利用這個引用激活java代碼把speed變量設為初始值另外一條指令會用這個引用激活Lava對象的flow()方法
()堆存放運行時所有對象和數(shù)組
()棧每次啟動一個新的線程就會被分配一個棧
()PC寄存器(程序計數(shù)器)
總是指向該線程下一步要執(zhí)行的指令指令的位置放在方法區(qū)的方法字節(jié)碼中內(nèi)容是相對于第一個指令的偏移量
lishixinzhi/Article/program/Java/hx/201311/26491
概念
特點
先進后出
虛擬機棧:用戶描述Java方法執(zhí)行的內(nèi)存模型
棧幀:虛擬機棧中的棧元素(用于支持虛擬機進行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu))包括局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口
1.主要存儲:
2.數(shù)據(jù)過多會導致OutOfMemoryError異常
JDK1.8
=JDK1.8
和永久代的區(qū)別:
1.存儲位置不同,永久代物理上是堆的一部分,和新手代,老年代地址是連續(xù)的,而元空間屬于本地內(nèi)存;
2.存儲內(nèi)容不同,元空間存儲類的元信息,靜態(tài)變量和常量池等并入堆中;
3.相當于永久代的數(shù)據(jù)被分到了堆和元空間中
直接內(nèi)存:避免native空間和java堆中來回進行復制
虛擬機啟動時創(chuàng)建,用于存放對象實例,幾乎所有的對象(包含常量池)都在堆上分配內(nèi)存,當對象無法再該空間申請到內(nèi)存時將拋出OutOfMemoryError異常。同時也是垃圾收集器管理的主要區(qū)域??赏ㄟ^-Xmx–Xms參數(shù)來分別指定最大堆和最小堆
GC主要管理區(qū)域,可以通過-Xmx和Xms來設置最大和最小值,也可以通過-XX:NewSize-XX:MaxNewSize設置年輕代初始大小
超出空間大小會拋出OutOfMemoryError異常
新生區(qū)
新生區(qū)分為兩個部分:伊甸區(qū)(Edenspace)和幸存者區(qū)(survivorspace)
伊甸區(qū)(Edenspace)
大部分對象都會在Eden區(qū)誕生,并且一段時間不使用就會被GC回收
幸存者區(qū)(survivorspace)
存在一段時間還在使用的對象會進入survivor區(qū),survivor區(qū)包含一個相對的From區(qū)和to區(qū),兩者來回copy,回收沒用的對象,用來延長對象的生命周期。
老年區(qū)(oldFullGC)
經(jīng)過多次GC仍然存在的對象會移動到老年區(qū)中,若老年區(qū)也滿了,則會產(chǎn)生MajorGC(FullGC),對老年區(qū)進行內(nèi)存清理(STW),若老年區(qū)執(zhí)行了FullGC之后發(fā)現(xiàn)還是無法進行對象的報錯,那么就會產(chǎn)生OOM異?!監(jiān)utOfMemoryError“
問題:空間不連續(xù),浪費空間
復制算法有2塊一樣大小的空間,情況對象時將可用的對象移動到to區(qū)里,復制算法內(nèi)存空間連續(xù)
問題:要用2塊空間,所以內(nèi)存的模型from和to非常的小
只用一塊空間,先進行標記無用對象,然后整理內(nèi)存空間地址,最后清除
它只有一條GC線程,且就像前面說的,它在運行的時候需要暫停用戶程序(stoptheworld)STW
它有多條GC線程,且它也需要暫停用戶程序(stoptheworld)STW
它有一條或多條GC線程,且它需要在部分階段暫停用戶程序(stoptheworld),部分階段與用戶程序并發(fā)執(zhí)行
serial(用于新生代,采用復制算法)、serialold(用于年老代,采用標記/整理算法)
parNew(用于新生代,采用復制算法)、Parallel
Scavenge(用于新生代,采用復制算法)、Parallel
old(用于年老代,采用標記/整理算法)
concurrentmarksweep[CMS](用于年老代,采用標記/清除算法)
JVM會試圖將系統(tǒng)內(nèi)存盡可能地限制在-Xms中,當內(nèi)存實際使用量觸及-Xms指定的大小時,會觸發(fā)FullGC。因此把-Xms值設置為-Xmx時,可以在系統(tǒng)運行初期減少GC操作的次數(shù)和耗時。
本文分類:科技
瀏覽次數(shù):1251次瀏覽
發(fā)布日期:2023-04-29 08:39:09
本文鏈接:http://www.tbamed.com/net/d826721e2b244c39ec31daedfd8a4c3a.html