在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/Java  Linux  網(wǎng)絡(luò)安全/ 進(jìn)程用到的虛擬內(nèi)存比物理內(nèi)存小是怎么回事?

進(jìn)程用到的虛擬內(nèi)存比物理內(nèi)存小是怎么回事?

下面進(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)存。

回答
編輯回答
只愛(à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í)踐出真知-----

2018年5月10日 12:40
編輯回答
撥弦

你的程序運(yùn)行在一個(gè)線程中,而線程運(yùn)行在java虛擬機(jī)中,虛擬機(jī)內(nèi)存又是由內(nèi)存來(lái),所以,內(nèi)存 > 虛擬機(jī)內(nèi)存 > 每個(gè)線程所開辟的內(nèi)存。

2018年7月17日 13:35