專(zhuān)注搜索競(jìng)價(jià)代運(yùn)營(yíng)

成長(zhǎng)之選 ,效果之道!

免費(fèi)咨詢(xún)熱線:17636682598

jvm內(nèi)存和系統(tǒng)內(nèi)存,jvm內(nèi)存和操作系統(tǒng)內(nèi)存

JVM內(nèi)存布局及演變-Xms1024m:設(shè)置初始化內(nèi)存分配大小,默認(rèn)為本地內(nèi)存的1/64。-Xmx1024m:設(shè)置最大分配內(nèi)存,默認(rèn)為本地內(nèi)存的1/4。底層方法,與native方法相關(guān)。線程私有,內(nèi)

JVM內(nèi)存布局及演變

-Xms1024m:設(shè)置初始化內(nèi)存分配大小,默認(rèn)為本地內(nèi)存的1/64。

-Xmx1024m:設(shè)置最大分配內(nèi)存,默認(rèn)為本地內(nèi)存的1/4。

底層方法,與native方法相關(guān)。

線程私有,內(nèi)存連續(xù),存放8大基本類(lèi)型+對(duì)象引用+實(shí)例的方法引用。

也叫PC寄存器,線程私有,保存當(dāng)前執(zhí)行指令的地址。

線程共享,內(nèi)存不連續(xù),存放對(duì)象實(shí)例。

-XX:+HeapDumpOnOutOfMemoryError:OOM

方法區(qū)是一個(gè)JVM規(guī)范上的邏輯概念,實(shí)際的位置根據(jù)不同JVM來(lái)看。

hotspotJVM虛擬機(jī)上將堆中的永久代作為方法區(qū)的一個(gè)存儲(chǔ)實(shí)現(xiàn),為的是方法區(qū)也可以用堆內(nèi)存的GC垃圾回收機(jī)制,而不用重新針對(duì)方法區(qū)做GC操作,直接使用堆內(nèi)存的GC就可以了。

存放靜態(tài)變量(static)、常量(final)、類(lèi)信息(Class,如構(gòu)造方法、接口定義)、常量池。實(shí)例變量存在堆內(nèi)存中,和方法區(qū)無(wú)關(guān)。

在Java7中永久代中存儲(chǔ)的部分?jǐn)?shù)據(jù)已經(jīng)開(kāi)始轉(zhuǎn)移到JavaHeap或NativeMemory中了。比如,符號(hào)引用(Symbols)轉(zhuǎn)移到了NativeMemory;字符串常量池(internedstrings)、類(lèi)的靜態(tài)變量(classstatics)轉(zhuǎn)移到了JavaHeap,永久代中存放類(lèi)和類(lèi)加載器的元數(shù)據(jù)信息。

移除堆中的永久區(qū),用占用本地內(nèi)存的元空間(MetaSpace)來(lái)代替,存放類(lèi)和類(lèi)加載器的元數(shù)據(jù)信息。

符號(hào)引用沒(méi)有存在元空間中,而是繼續(xù)存在nativeheap中,這是兩個(gè)方式和位置,不過(guò)都可以算作是本地內(nèi)存,在虛擬機(jī)之外進(jìn)行劃分,沒(méi)有設(shè)置限制參數(shù)時(shí)只受物理內(nèi)存大小限制,即只有占滿(mǎn)了操作系統(tǒng)可用內(nèi)存后才OOM。

-XX:MetaspaceSize來(lái)調(diào)整元空間初始大小,最大為本地內(nèi)存大小。

感謝您的閱讀,本文已同步到我的個(gè)人博客,您的關(guān)注是對(duì)我最大的鼓勵(lì)!

Java程序運(yùn)行時(shí),操作系統(tǒng)內(nèi)存與JVM內(nèi)存的各自作用???

當(dāng)然。

把JVM看成是個(gè)中間層就可以,不止是內(nèi)存分配,還有線程、網(wǎng)絡(luò)連接等等,最終在底層都要靠操作系統(tǒng)來(lái)搞。

Java語(yǔ)言的設(shè)計(jì)思想,本來(lái)就是對(duì)C語(yǔ)言這種可以直接進(jìn)行操作系統(tǒng)調(diào)用的語(yǔ)言的一種簡(jiǎn)化。引入了一個(gè)隔離層,讓jvm來(lái)當(dāng)個(gè)中介,以簡(jiǎn)化應(yīng)用開(kāi)發(fā)。讓程序員集中精力于實(shí)現(xiàn)業(yè)務(wù)邏輯。

JVM內(nèi)存管理

JVM全稱(chēng)JavaVirtualMachine,也就是我們耳熟能詳?shù)腏ava虛擬機(jī)。它能識(shí)別.class后綴的文件,并且能夠解析它的指令,最終調(diào)用操作系統(tǒng)上的函數(shù),完成我們想要的操作。

元空間大小參數(shù):

堆大小參數(shù):

-Xms:堆的最小值;

-Xmx:堆的最大值;

-Xmn:新生代的大??;

-XX:NewSize;新生代最小值;

-XX:MaxNewSize:新生代最大值;

例如-Xmx256m

功能

(1)運(yùn)行時(shí)常量池溢出

(2)方法區(qū)中保存的Class對(duì)象沒(méi)有被及時(shí)回收掉或者Class信息占用的內(nèi)存超過(guò)了我們配置。

注意Class要被回收,條件比較苛刻(僅僅是可以,不代表必然,因?yàn)檫€有一些參數(shù)可以進(jìn)行控制):

1、該類(lèi)所有的實(shí)例都已經(jīng)被回收,也就是堆中不存在該類(lèi)的任何實(shí)例。

2、加載該類(lèi)的ClassLoader已經(jīng)被回收。

3、該類(lèi)對(duì)應(yīng)的java.lang.Class對(duì)象沒(méi)有在任何地方被引用,無(wú)法在任何地方通過(guò)反射訪問(wèn)該類(lèi)的方法。

JVM內(nèi)存結(jié)構(gòu)

()類(lèi)裝載子系統(tǒng)

裝載連接初始化

()方法區(qū)被所有線程共享垃圾收集也會(huì)清理方法區(qū)中的無(wú)用類(lèi)型對(duì)象

a類(lèi)型信息類(lèi)加載器加載類(lèi)時(shí)從類(lèi)文件中提取出來(lái)

類(lèi)的完整有效名

父類(lèi)的完整有效名(interfaceandjavalangObject除外因?yàn)闊o(wú)父類(lèi))

類(lèi)型的修飾符

類(lèi)型直接接口列表

b常量池存儲(chǔ)了一個(gè)類(lèi)型所使用的常量所有類(lèi)型域和方法的符號(hào)引用

c域信息jvm必須在方法區(qū)中保存類(lèi)型的所有域的相關(guān)信息以及域的聲明順序

域的相關(guān)信息包括

域名

域類(lèi)型

域修飾符(publicprivateprotectedstaticfinalvolatiletransient…)

d方法信息

方法名

方法返回類(lèi)型

方法參數(shù)

方法的修飾符

方法的字節(jié)碼(abstractandnative除外)(被PC寄存器指向)

操作數(shù)棧和方法棧幀的局部變量區(qū)的大小

異常表

e類(lèi)的靜態(tài)變量(所有對(duì)象共享一分拷貝)

f類(lèi)的被聲明為final的類(lèi)變量(所有對(duì)象共享一分拷貝)

g加載一個(gè)類(lèi)的類(lèi)加載器的引用

hClass類(lèi)的引用

i方法表

j一個(gè)例子

ClassLava{

privateintspeed=;

voidflow();

}

ClassVolcano{

publicstaticvoidmain(String[]args){

Lavalava=newLava();

lavaflow();

}

}

下面我們描述一下main()方法的第一條指令的字節(jié)碼是如何被執(zhí)行的不同的jvm實(shí)現(xiàn)的差別很大這里只是其中之一

為了運(yùn)行這個(gè)程序你以某種方式把Volcano傳給了jvm有了這個(gè)名字jvm找到了這個(gè)類(lèi)文件(Volcanoclass)并讀入它從類(lèi)文件提取了類(lèi)型信息并放在了方法區(qū)中通過(guò)解析存在方法區(qū)中的字節(jié)碼jvm激活了main()方法在執(zhí)行時(shí)jvm保持了一個(gè)指向當(dāng)前類(lèi)(Volcano)常量池的指針

注意jvm在還沒(méi)有加載Lava類(lèi)的時(shí)候就已經(jīng)開(kāi)始執(zhí)行了正像大多數(shù)的jvm一樣不會(huì)等所有類(lèi)都加載了以后才開(kāi)始執(zhí)行它只會(huì)在需要的時(shí)候才加載

main()的第一條指令告知jvm為列在常量池第一項(xiàng)的類(lèi)分配足夠的內(nèi)存

jvm使用指向Volcano常量池的指針找到第一項(xiàng)發(fā)現(xiàn)是一個(gè)對(duì)Lava類(lèi)的符號(hào)引用然后它就檢查方法區(qū)看lava是否已經(jīng)被加載了

這個(gè)符號(hào)引用僅僅是類(lèi)lava的完整有效名lava這里我們看到為了jvm能盡快從一個(gè)名稱(chēng)找到一個(gè)類(lèi)一個(gè)良好的數(shù)據(jù)結(jié)構(gòu)是多么重要這里jvm的實(shí)現(xiàn)者可以采用各種方法如hash表查找樹(shù)等等同樣的算法可以用于Class類(lèi)的forName()的實(shí)現(xiàn)

當(dāng)jvm發(fā)現(xiàn)還沒(méi)有加載過(guò)一個(gè)稱(chēng)為L(zhǎng)ava的類(lèi)它就開(kāi)始查找并加載類(lèi)文件Lavaclass它從類(lèi)文件中抽取類(lèi)型信息并放在了方法區(qū)中

jvm于是以一個(gè)直接指向方法區(qū)lava類(lèi)的指針替換了常量池第一項(xiàng)的符號(hào)引用以后就可以用這個(gè)指針快速的找到lava類(lèi)了而這個(gè)替換過(guò)程稱(chēng)為常量池解析(constantpoolresolution)在這里我們替換的是一個(gè)native指針

jvm終于開(kāi)始為新的lava對(duì)象分配空間了這次jvm仍然需要方法區(qū)中的信息它使用指向lava數(shù)據(jù)的指針(剛才指向volcano常量池第一項(xiàng)的指針)找到一個(gè)lava對(duì)象究竟需要多少空間

一旦jvm知道了一個(gè)Lava對(duì)象所要的空間它就在堆上分配這個(gè)空間并把這個(gè)實(shí)例的變量speed初始化為缺省值假如lava的父對(duì)象也有實(shí)例變量則也會(huì)初始化

當(dāng)把新生成的lava對(duì)象的引用壓到棧中第一條指令也結(jié)束了下面的指令利用這個(gè)引用激活java代碼把speed變量設(shè)為初始值另外一條指令會(huì)用這個(gè)引用激活Lava對(duì)象的flow()方法

()堆存放運(yùn)行時(shí)所有對(duì)象和數(shù)組

()棧每次啟動(dòng)一個(gè)新的線程就會(huì)被分配一個(gè)棧

()PC寄存器(程序計(jì)數(shù)器)

總是指向該線程下一步要執(zhí)行的指令指令的位置放在方法區(qū)的方法字節(jié)碼中內(nèi)容是相對(duì)于第一個(gè)指令的偏移量

lishixinzhi/Article/program/Java/hx/201311/26491

JVM基礎(chǔ)和內(nèi)存區(qū)域剖析

概念

特點(diǎn)

先進(jìn)后出

虛擬機(jī)棧:用戶(hù)描述Java方法執(zhí)行的內(nèi)存模型

棧幀:虛擬機(jī)棧中的棧元素(用于支持虛擬機(jī)進(jìn)行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu))包括局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口

1.主要存儲(chǔ):

2.數(shù)據(jù)過(guò)多會(huì)導(dǎo)致OutOfMemoryError異常

JDK1.8

=JDK1.8

和永久代的區(qū)別:

1.存儲(chǔ)位置不同,永久代物理上是堆的一部分,和新手代,老年代地址是連續(xù)的,而元空間屬于本地內(nèi)存;

2.存儲(chǔ)內(nèi)容不同,元空間存儲(chǔ)類(lèi)的元信息,靜態(tài)變量和常量池等并入堆中;

3.相當(dāng)于永久代的數(shù)據(jù)被分到了堆和元空間中

直接內(nèi)存:避免native空間和java堆中來(lái)回進(jìn)行復(fù)制

虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,用于存放對(duì)象實(shí)例,幾乎所有的對(duì)象(包含常量池)都在堆上分配內(nèi)存,當(dāng)對(duì)象無(wú)法再該空間申請(qǐng)到內(nèi)存時(shí)將拋出OutOfMemoryError異常。同時(shí)也是垃圾收集器管理的主要區(qū)域??赏ㄟ^(guò)-Xmx–Xms參數(shù)來(lái)分別指定最大堆和最小堆

GC主要管理區(qū)域,可以通過(guò)-Xmx和Xms來(lái)設(shè)置最大和最小值,也可以通過(guò)-XX:NewSize-XX:MaxNewSize設(shè)置年輕代初始大小

超出空間大小會(huì)拋出OutOfMemoryError異常

新生區(qū)

新生區(qū)分為兩個(gè)部分:伊甸區(qū)(Edenspace)和幸存者區(qū)(survivorspace)

伊甸區(qū)(Edenspace)

大部分對(duì)象都會(huì)在Eden區(qū)誕生,并且一段時(shí)間不使用就會(huì)被GC回收

幸存者區(qū)(survivorspace)

存在一段時(shí)間還在使用的對(duì)象會(huì)進(jìn)入survivor區(qū),survivor區(qū)包含一個(gè)相對(duì)的From區(qū)和to區(qū),兩者來(lái)回copy,回收沒(méi)用的對(duì)象,用來(lái)延長(zhǎng)對(duì)象的生命周期。

老年區(qū)(oldFullGC)

經(jīng)過(guò)多次GC仍然存在的對(duì)象會(huì)移動(dòng)到老年區(qū)中,若老年區(qū)也滿(mǎn)了,則會(huì)產(chǎn)生MajorGC(FullGC),對(duì)老年區(qū)進(jìn)行內(nèi)存清理(STW),若老年區(qū)執(zhí)行了FullGC之后發(fā)現(xiàn)還是無(wú)法進(jìn)行對(duì)象的報(bào)錯(cuò),那么就會(huì)產(chǎn)生OOM異常”O(jiān)utOfMemoryError“

問(wèn)題:空間不連續(xù),浪費(fèi)空間

復(fù)制算法有2塊一樣大小的空間,情況對(duì)象時(shí)將可用的對(duì)象移動(dòng)到to區(qū)里,復(fù)制算法內(nèi)存空間連續(xù)

問(wèn)題:要用2塊空間,所以?xún)?nèi)存的模型from和to非常的小

只用一塊空間,先進(jìn)行標(biāo)記無(wú)用對(duì)象,然后整理內(nèi)存空間地址,最后清除

它只有一條GC線程,且就像前面說(shuō)的,它在運(yùn)行的時(shí)候需要暫停用戶(hù)程序(stoptheworld)STW

它有多條GC線程,且它也需要暫停用戶(hù)程序(stoptheworld)STW

它有一條或多條GC線程,且它需要在部分階段暫停用戶(hù)程序(stoptheworld),部分階段與用戶(hù)程序并發(fā)執(zhí)行

serial(用于新生代,采用復(fù)制算法)、serialold(用于年老代,采用標(biāo)記/整理算法)

parNew(用于新生代,采用復(fù)制算法)、Parallel

Scavenge(用于新生代,采用復(fù)制算法)、Parallel

old(用于年老代,采用標(biāo)記/整理算法)

concurrentmarksweep[CMS](用于年老代,采用標(biāo)記/清除算法)

JVM內(nèi)存分配參數(shù)

JVM會(huì)試圖將系統(tǒng)內(nèi)存盡可能地限制在-Xms中,當(dāng)內(nèi)存實(shí)際使用量觸及-Xms指定的大小時(shí),會(huì)觸發(fā)FullGC。因此把-Xms值設(shè)置為-Xmx時(shí),可以在系統(tǒng)運(yùn)行初期減少GC操作的次數(shù)和耗時(shí)。

本文分類(lèi):科技

瀏覽次數(shù):1251次瀏覽

發(fā)布日期:2023-04-29 08:39:09

本文鏈接:http://godcuan.com/net/d826721e2b244c39ec31daedfd8a4c3a.html