死磕內存篇 --- JAVA進程和linux內存間的大小關係

 

 

運行個JAVA 用sleep去hold住java

複製代碼

package org.hjb.test; 

public class TestOnly { 
public static void main(String[] args) { 

System.out.println("sleep .."); 
try { 
Thread.sleep(10000000); 
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
} 
}

複製代碼

 

 

java -Xmx10m -Xms10m org/hjb/test/TestOnlylinux

 

 

 

 

從Jvm進程的角度觀察socket

 

查看JAVA進程的整體內存大小ide

 

原始參數         java -Xmx10m -Xms10m org/hjb/test/TestOnly   後觀察結果:函數

 

PID    USER  PR   NI      VIRT         RES       SHR    S    %CPU  %MEM     TIME+  COMMAND 
27182  root   20    0      1182152      40452     13596  S     0.0   1.0     :00.27   java

 

 

變換參數          java -Xmx1024m -Xms1024m org/hjb/test/TestOnly   後觀察spa

 

1線程

27278   root   20  0     2258424      31656    13776 S     0.0       0.8       0:00.16     java   code

  

 

繼續變換參數   java -Xmx2024m -Xms2024m org/hjb/test/TestOnly   後觀察對象

 

27297 root  20   0     3319832     34876     13668 S    0.0       0.9       0:00.10     java

上面觀察能夠得出進程

提升JAVA的堆內存分配,影響的只是VIRT內存的使用狀況。 詳附1

 

 

實驗二:

觀察JAVA的實際使用內存,  JAVA進程的實際使用內存應該包括, JVM的內存+JAVA程序的內存 詳附2

 

運行 java -Xmx2048m -Xms2048m org/hjb/test/TestOnly  觀察

 

PID    USER   PR    NI     VIRT          RES        SHR     S    %CPU  %MEM      TIME+  COMMAND 
27406   root    20   0      3345308       35000      13716   S    0.0   0.9       0:00.21   java

 

 

修改程序

複製代碼

package org.hjb.test; 
public class TestOnly { 
public static void main(String[] args) { 

System.out.println("sleep .."); 
try { 
byte[] buf = new byte[1024 * 1024 * 1024];  //1g  增大其內存
Thread.sleep(10000000); 
} catch (InterruptedException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
} 
} 
}

複製代碼

 

 

運行 java -Xmx2048m -Xms2048m org/hjb/test/TestOnly  觀察

 

PID    USER  PR        NI        VIRT          RES          SHR   S    %CPU  %MEM      TIME+        COMMAND 
 27445  root  20         0        3345308      1.034g        13688 S    0.0    26.8     0:00.89      java

 

 

 

上面觀察能夠得出

JAVA 程序中實際使用內存纔會佔用到內存,此時查看JAVA的內存

 

 

 

 

經過實驗, 設想只有當前用到了內存纔會進RES?

 

後面是經過線上問題發現不是如此, 由於若是沒有釋放的內存,仍是在RES的, 好比JDK的沒觸發,那麼內存就一直佔用 了RES.  因此內存大小仍是能夠直接影響到JAVA進程的大小

 

JAVA進程內存 = JVM進程內存+heap內存+ 永久代內存+ 本地方法棧內存+線程棧內存 +堆外內存 +socket 緩衝區內存

 

linux內存和JAVA堆中的關係

 

RES = JAVA正在存活的內存對象大小 + 未回收的對象大小  + 其它

 

VIART= JAVA中申請的內存大小,即 -Xmx  -Xms + 其它

 

其它 = 永久代內存+ 本地方法棧內存+線程棧內存 +堆外內存 +socket 緩衝區內存 +JVM進程內存

 

 

附1:

 

VIRT:virtual memory usage 
一、進程「須要的」虛擬內存大小,包括進程使用的庫、代碼、數據等 
二、假如進程申請100m的內存,但實際只使用了10m,那麼它會增加100m,而不是實際的使用量 
RES:resident memory usage 常駐內存 
一、進程當前使用的內存大小,但不包括swap out 
二、包含其餘進程的共享 
三、若是申請100m的內存,實際使用10m,它只增加10m,與VIRT相反 
四、關於庫佔用內存的狀況,它只統計加載的庫文件所佔內存大小 
SHR:shared memory 
一、除了自身進程的共享內存,也包括其餘進程的共享內存 
二、雖然進程只使用了幾個共享庫的函數,但它包含了整個共享庫的大小 
三、計算某個進程所佔的物理內存大小公式:RES – SHR 
四、swap out後,它將會降下來DATA一、數據佔用的內存。若是top沒有顯示,按f鍵能夠顯示出來。 
二、真正的該程序要求的數據空間,是真正在運行中要使用的。

 

 

附2:

相關文章
相關標籤/搜索