日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

面试准备之内存管理

發(fā)布時(shí)間:2024/9/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试准备之内存管理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、內(nèi)存管理原理

  在java中,有java程序、虛擬機(jī)、操作系統(tǒng)三個(gè)層次,其中java程序與虛擬機(jī)交互,而虛擬機(jī)與操作系統(tǒng)間交互!這就保證了java程序的平臺(tái)無(wú)關(guān)性!下面我們從程序運(yùn)行前,程序運(yùn)行中、程序運(yùn)行內(nèi)存溢出三個(gè)階段來(lái)說一下內(nèi)存管理原理!

1、程序運(yùn)行前:JVM向操作系統(tǒng)請(qǐng)求一定的內(nèi)存空間,稱為初始內(nèi)存空間!程序執(zhí)行過程中所需的內(nèi)存都是由java虛擬機(jī)從這片內(nèi)存空間中劃分的。 2、程序運(yùn)行中:java程序一直向java虛擬機(jī)申請(qǐng)內(nèi)存,當(dāng)程序所需要的內(nèi)存空間超出初始內(nèi)存空間時(shí),java虛擬機(jī)會(huì)再次向操作系統(tǒng)申請(qǐng)更多的內(nèi)存供程序使用! 3、內(nèi)存溢出:程序接著運(yùn)行,當(dāng)java虛擬機(jī)已申請(qǐng)的內(nèi)存達(dá)到了規(guī)定的最大內(nèi)存空間,但程序還需要更多的內(nèi)存,這時(shí)會(huì)出現(xiàn)內(nèi)存溢出的錯(cuò)誤!

至此可以看出,Java 程序所使用的內(nèi)存是由 Java 虛擬機(jī)進(jìn)行管理、分配的。Java 虛擬機(jī)規(guī)定了 Java 程序的初始內(nèi)存空間和最大內(nèi)存空間,開發(fā)者只需要關(guān)心 Java 虛擬機(jī)是如何管理內(nèi)存空間的,而不用關(guān)心某一種操作系統(tǒng)是如何管理內(nèi)存的。

?

二、內(nèi)存空間邏輯劃分

  JVM 會(huì)把申請(qǐng)的內(nèi)存從邏輯上劃分為三個(gè)區(qū)域,即:方法區(qū)、堆與棧。?

方法區(qū):方法區(qū)默認(rèn)最大容量為64M,Java虛擬機(jī)會(huì)將加載的java類存入方法區(qū),保存類的結(jié)構(gòu)(屬性與方法),類靜態(tài)成員等內(nèi)容。? :默認(rèn)最大容量為64M,堆存放對(duì)象持有的數(shù)據(jù),同時(shí)保持對(duì)原類的引用。可以簡(jiǎn)單的理解為對(duì)象屬性的值保存在堆中,對(duì)象調(diào)用的方法保存在方法區(qū)。 棧(虛擬機(jī)棧):棧默認(rèn)最大容量為1M,在程序運(yùn)行時(shí),每當(dāng)遇到方法調(diào)用時(shí),Java虛擬機(jī)就會(huì)在棧中劃分一塊內(nèi)存稱為棧幀(Stack frame),棧幀中的內(nèi)存供局部變量(包括基本類型與引用類型)使用,當(dāng)方法調(diào)用結(jié)束后,Java虛擬機(jī)會(huì)收回此棧幀占用的內(nèi)存。 運(yùn)行時(shí)常量池:是方法區(qū)的一部分。用于存放編譯期生成的各種字面量和符號(hào)引用,這部分內(nèi)容將在類加載后存放到方法去的運(yùn)行時(shí)常量池中。 程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。在虛擬機(jī)的概念模型里(僅是概念模型,各種虛擬機(jī)可能會(huì)通過一些更高效的方式去實(shí)現(xiàn)),字節(jié)碼解釋器工作時(shí)就是通過改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來(lái)完成。如果線程正在執(zhí)行的是一個(gè)Java方法,這個(gè)計(jì)數(shù)器

記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址;如果正在執(zhí)行的是Natvie方法,這個(gè)計(jì)數(shù)器值則為空(Undefined)。此內(nèi)存區(qū)域是唯一一個(gè)Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError情況的區(qū)域。

  本地方法棧(Native Method Stacks)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的,其區(qū)別不過是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。虛擬機(jī)規(guī)范中對(duì)本地方法棧中的方法使用的語(yǔ)言、使用方式與數(shù)據(jù)結(jié)構(gòu)并沒有強(qiáng)制規(guī)定,因此具體的虛擬機(jī)可以自由實(shí)現(xiàn)它

?

三、java數(shù)據(jù)類型 1、基本數(shù)據(jù)類型:沒封裝指針的變量。 聲明此類型變量,只會(huì)在棧中分配一塊內(nèi)存空間。 2、引用類型:就是底層封裝指針的數(shù)據(jù)類型。 他們?cè)趦?nèi)存中分配兩塊空間,第一塊內(nèi)存分配在棧中,只存放別的內(nèi)存地址,不存放具體數(shù)值,我們也把它叫指針類型的變量,第二塊內(nèi)存分配在堆中,存放的是具體數(shù)值,如對(duì)象屬性值等。 3、下面我們從一個(gè)例子來(lái)看一看: public class Student {? String stuId;? String stuName;? int stuAge;? }? public class TestStudent {? public static void main(String[] args) {? Student zhouxingxing = new Student();? String name = new String("旺旺"); ? int a = 10;? char b = 'm';? zhouxingxing.stuId = "9527";? zhouxingxing.stuName = "周星星";? zhouxingxing.stuAge = 25;? }? } (1)類當(dāng)然是存放在方法區(qū)里面的。 (2)Student zhouxingxing = new Student();? 這行代碼就創(chuàng)建了兩塊內(nèi)存空間,第一個(gè)在棧中,名字叫zhouxingxing,它就相當(dāng)于指針類型的變量,我們看到它并不存放學(xué)生的姓名、年齡等具體的數(shù)值,而是存放堆中第二塊內(nèi)存的地址,第二塊才存放具體的數(shù)值,如學(xué)生的編號(hào)、姓名、年齡等信息。 (3)int a = 10;?這是?基本數(shù)據(jù)類型?變量,具體的值就存放在棧中,并沒有只指針的概念! 四、值傳參和引用傳參 (1)參數(shù)根據(jù)調(diào)用后的效果不同,即是否改變參數(shù)的原始數(shù)值,又可以分為兩種:按值傳遞的參數(shù)與按引用傳遞的參數(shù)。 按值傳遞的參數(shù)原始數(shù)值不改變,按引用傳遞的參數(shù)原始數(shù)值改變!這是為什么呢?其實(shí)相當(dāng)簡(jiǎn)單: 我們知道基本數(shù)據(jù)類型的變量存放在棧里面,變量名處存放的就是變量的值,那么當(dāng)基本數(shù)據(jù)類型的變量作為參數(shù)時(shí),傳遞的就是這個(gè)值,只是把變量的值傳遞了過去,不管對(duì)這個(gè)值如何操作,都不會(huì)改變變量的原始值。而對(duì)引用數(shù)據(jù)類型的變量來(lái)說,變量名處存放的地址,所以引用數(shù)據(jù)類型的變量作為傳參時(shí),傳遞的實(shí)際上是地址,對(duì)地址處的內(nèi)容進(jìn)行操作,當(dāng)然會(huì)改變變量的值了! 五、內(nèi)存區(qū)域調(diào)節(jié)參數(shù)

  -Xms:初始堆大小,默認(rèn)為物理內(nèi)存的1/64(<1GB);默認(rèn)(MinHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存小于40%時(shí),JVM就會(huì)增大堆直到-Xmx的最大限制

  -Xmx:最大堆大小,默認(rèn)(MaxHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于70%時(shí),JVM會(huì)減少堆直到 -Xms的最小限制

  -Xmn:新生代的內(nèi)存空間大小,注意:此處的大小是(eden+ 2 survivor space)。與jmap -heap中顯示的New gen是不同的。整個(gè)堆大小=新生代大小 + 老生代大小 + 永久代大小。?
在保證堆大小不變的情況下,增大新生代后,將會(huì)減小老生代大小。此值對(duì)系統(tǒng)性能影響較大,Sun官方推薦配置為整個(gè)堆的3/8。

  -XX:SurvivorRatio:新生代中Eden區(qū)域與Survivor區(qū)域的容量比值,默認(rèn)值為8。兩個(gè)Survivor區(qū)與一個(gè)Eden區(qū)的比值為2:8,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/10。

  -Xss:每個(gè)線程的堆棧大小。JDK5.0以后每個(gè)線程堆棧大小為1M,以前每個(gè)線程堆棧大小為256K。應(yīng)根據(jù)應(yīng)用的線程所需內(nèi)存大小進(jìn)行適當(dāng)調(diào)整。在相同物理內(nèi)存下,減小這個(gè)值能生成更多的線程。但是操作系統(tǒng)對(duì)一個(gè)進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無(wú)限生成,經(jīng)驗(yàn)值在3000~5000左右。一般小的應(yīng)用, 如果棧不是很深, 應(yīng)該是128k夠用的,大的應(yīng)用建議使用256k。這個(gè)選項(xiàng)對(duì)性能影響比較大,需要嚴(yán)格的測(cè)試。和threadstacksize選項(xiàng)解釋很類似,官方文檔似乎沒有解釋,在論壇中有這樣一句話:"-Xss is translated in a VM flag named ThreadStackSize”一般設(shè)置這個(gè)值就可以了。

  -XX:PermSize:設(shè)置永久代(perm gen)初始值。默認(rèn)值為物理內(nèi)存的1/64。

  -XX:MaxPermSize:設(shè)置持久代最大值。物理內(nèi)存的1/4。

?

參考:

http://liu1227787871.blog.163.com/blog/static/205363197201263103320466/

http://www.blogjava.net/chhbjh/archive/2012/01/28/368936.html

http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html

轉(zhuǎn)載于:https://www.cnblogs.com/wabi87547568/p/5284110.html

總結(jié)

以上是生活随笔為你收集整理的面试准备之内存管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。