下面進(jìn)程用到的虛擬內(nèi)存比物理內(nèi)存小是怎么回事?
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
246 root 20 0 7070m 2.5g 10m S 0.4 4.0 58:42.39 java
我的理解是,虛擬內(nèi)存應(yīng)該比物理內(nèi)存大啊,虛擬內(nèi)存包括申請(qǐng)的內(nèi)存,而物理內(nèi)存是實(shí)際使用的內(nèi)存
譬如
List list = new ArrayList<String>(1000);
list.add("abcd");
這里申請(qǐng)了1000個(gè),所以虛擬內(nèi)存大小是1000個(gè)String的大小,但是物理內(nèi)存就是“abcd”這個(gè)字符串占的內(nèi)存。
virt 7070m
你的java程序能訪問(wèn)的內(nèi)存空間地址, 包括代碼,數(shù)據(jù),共享庫(kù),交換頁(yè)等等, 這是一個(gè)虛擬映射, 并不是所有地址都有相應(yīng)的物理內(nèi)存對(duì)應(yīng), 所以可以是大于物理內(nèi)存的.res 2.5g
這個(gè)可能和你的java啟動(dòng)參數(shù)有關(guān), 如 -Xmx2500m或比這個(gè)還大, 是程序占用的非交換的駐留內(nèi)存.shr 10m
占用內(nèi)存的可共享部分,可能與其他進(jìn)行共用.%mem 4.0
占用內(nèi)存的百分比
推測(cè) 2.5g/4%=62.5~你的機(jī)器有64G的物理內(nèi)存
至于代碼
List list = new ArrayList<String>(1000);
list.add("abcd");
可以這樣理解內(nèi)存使用new ArrayList<String>(1000); 僅僅是分配并初始化了一個(gè)ArrayList對(duì)象. 并初始化的內(nèi)部的數(shù)組對(duì)象
我們看一下JDK6的源碼
127 public ArrayList(int initialCapacity) {
128 super(); //調(diào)用AbstractList的默認(rèn)構(gòu)造函數(shù),里面什么也沒(méi)有做
129 if (initialCapacity < 0)
130 throw new IllegalArgumentException("Illegal Capacity: "+
131 initialCapacity);
132 this.elementData = new Object[initialCapacity]; //創(chuàng)建一個(gè)數(shù)組對(duì)象
133 }
真正消耗內(nèi)存的是 new Object[initialCapacity], 大約是initialCapacity*4個(gè)字節(jié), 算下來(lái)也不多.
list.add("abcd")增加了一個(gè)string對(duì)象加對(duì)象內(nèi)部字符和屬性(長(zhǎng)度等)占用的內(nèi)存.
可以用下面的小程序完成對(duì)內(nèi)存使用的檢驗(yàn)
import java.util.*;
public class test{
public static void print(){
long total = Runtime.getRuntime().totalMemory();
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
System.out.println("total="+total+" used="+used);
}
public static void main(String[] args)throws Exception {
print(); //(1)
List<String> list = new ArrayList<>(1000000);
print(); //(2)
Thread.sleep(1000);
int i=0;
while(i++<1000000){
list.add(i+"test1234567890");
}
print();//(3)
Thread.sleep(10000);
}
}
代碼里的Thread.sleep的作用是為了占用內(nèi)存時(shí)間長(zhǎng)一下,這樣可以用終端指令進(jìn)行監(jiān)控
top -p `pgrep java`
上面的程序執(zhí)行后輸出的結(jié)果為
total=55574528 used=608336 (1)
total=55574528 used=4608352 (2)
total=204472320 used=85200512 (3)
上面(2)-(1) 4608352-608336= 4000016
對(duì)應(yīng)的是ArrayList對(duì)象占16字節(jié), elementData數(shù)組每個(gè)占4字節(jié),共1Mx4=4M內(nèi)存.
放入字符串后, 85200512-4608352=80592160, 大概我的每個(gè)測(cè)試字符串占用了80字節(jié),實(shí)際字符平均20個(gè), 每個(gè)字符占用的也是4個(gè)字節(jié).
-----實(shí)踐出真知-----
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。