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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 物理内存_聊聊Java中的内存

發(fā)布時間:2023/12/4 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 物理内存_聊聊Java中的内存 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JVM的內(nèi)存

先放一張JVM的內(nèi)存劃分圖,總體上可以分為堆和非堆(粗略劃分,基于java8)

那么一個Java進(jìn)程最大占用的物理內(nèi)存為:

Max Memory = eden + survivor + old + String Constant Pool + Code cache + compressed class space + Metaspace + Thread stack(*thread num) + Direct + Mapped + JVM + Native Memory

堆和非堆內(nèi)存

堆和非堆內(nèi)存有以下幾個概念:

init

表示JVM在啟動時從操作系統(tǒng)申請內(nèi)存管理的初始內(nèi)存大小(以字節(jié)為單位)。JVM可能從操作系統(tǒng)請求額外的內(nèi)存,也可以隨著時間的推移向操作系統(tǒng)釋放內(nèi)存(經(jīng)實際測試,這個內(nèi)存并沒有過主動釋放)。這個init的值可能不會定義。

used

表示當(dāng)前使用的內(nèi)存量(以字節(jié)為單位)

committed

表示保證可供 Jvm使用的內(nèi)存大小(以字節(jié)為單位)。 已提交內(nèi)存的大小可能隨時間而變化(增加或減少)。 JVM也可能向系統(tǒng)釋放內(nèi)存,導(dǎo)致已提交的內(nèi)存可能小于 init,但是committed永遠(yuǎn)會大于等于used。

max

表示可用于內(nèi)存管理的最大內(nèi)存(以字節(jié)為單位)。

NMT追蹤內(nèi)存

NMT(Native Memory tracking)是一種Java HotSpot VM功能,可跟蹤Java HotSpot VM的內(nèi)部內(nèi)存使用情況(jdk8+)。

本文簡單介紹下該工具的使用,主要用來解釋Java中的內(nèi)存

開啟

在啟動參數(shù)中添加-XX:NativeMemoryTracking=detail

查看

jcmd 進(jìn)程id VM.native_memory summary scale=MB

輸出結(jié)果

Native Memory Tracking:

Total: reserved=6988749KB, committed=3692013KB

堆內(nèi)存

- Java Heap (reserved=5242880KB, committed=3205008KB)

(mmap: reserved=5242880KB, committed=3205008KB)

類加載信息

- Class (reserved=1114618KB, committed=74642KB)

(classes #10657)

(malloc=4602KB #32974)

(mmap: reserved=1110016KB, committed=70040KB)

線程棧

- Thread (reserved=255213KB, committed=255213KB)

(thread #248)

(stack: reserved=253916KB, committed=253916KB)

(malloc=816KB #1242)

(arena=481KB #494)

代碼緩存

- Code (reserved=257475KB, committed=46551KB)

(malloc=7875KB #10417)

(mmap: reserved=249600KB, committed=38676KB)

垃圾回收

- GC (reserved=31524KB, committed=23560KB)

(malloc=17180KB #2113)

(mmap: reserved=14344KB, committed=6380KB)

編譯器

- Compiler (reserved=598KB, committed=598KB)

(malloc=467KB #1305)

(arena=131KB #3)

內(nèi)部

- Internal (reserved=6142KB, committed=6142KB)

(malloc=6110KB #23691)

(mmap: reserved=32KB, committed=32KB)

符號

- Symbol (reserved=11269KB, committed=11269KB)

(malloc=8544KB #89873)

(arena=2725KB #1)

nmt

- Native Memory Tracking (reserved=2781KB, committed=2781KB)

(malloc=199KB #3036)

(tracking overhead=2582KB)

- Arena Chunk (reserved=194KB, committed=194KB)

(malloc=194KB)

- Unknown (reserved=66056KB, committed=66056KB)

(mmap: reserved=66056KB, committed=66056KB)

nmt返回結(jié)果中有reserved和committed兩個值,這里解釋一下:

reserved

reserved memory 是指JVM 通過mmaped PROT_NONE 申請的虛擬地址空間,在頁表中已經(jīng)存在了記錄(entries),說白了,就是已分配的大小

在堆內(nèi)存下,就是xmx值,jvm申請的最大保留內(nèi)存。

committed

committed memory 是JVM向操做系統(tǒng)實際分配的內(nèi)存(malloc/mmap),mmaped PROT_READ | PROT_WRITE,相當(dāng)于程序?qū)嶋H申請的可用內(nèi)存。

在堆內(nèi)存下,當(dāng)xms沒有擴(kuò)容時就是xms值,最小堆內(nèi)存,擴(kuò)容后就是擴(kuò)容后的值,heap committed memory,。

注意,committed申請的內(nèi)存并不是說直接占用了物理內(nèi)存,由于操作系統(tǒng)的內(nèi)存管理是惰性的,對于已申請的內(nèi)存雖然會分配地址空間,但并不會直接占用物理內(nèi)存,真正使用的時候才會映射到實際的物理內(nèi)存。所以committed > res也是很可能的

Linux內(nèi)存與JVM內(nèi)存

再來說說JVM內(nèi)存與該進(jìn)程的內(nèi)存。

現(xiàn)在有一個Java進(jìn)程,JVM所有已使用內(nèi)存區(qū)域加起來才2G(不包括Native Memory,也沒有顯式調(diào)用JNI的地方),但從top/pmap上看該進(jìn)程res已經(jīng)2.9G了

#heap + noheap

Memory used total max usage

heap 1921M 2822M 4812M 39.93%

par_eden_space 1879M 2457M 2457M 76.47%

par_survivor_space 4M 307M 307M 1.56%

cms_old_gen 37M 57M 2048M 1.84%

nonheap 103M 121M -1 85.00%

code_cache 31M 37M 240M 13.18%

metaspace 63M 74M -1 85.51%

compressed_class_space 7M 9M 1024M 0.75%

direct 997K 997K - 100.00

mapped 0K 0K - NaN%

#top

top -p 6267

top - 17:39:40 up 140 days, 5:39, 5 users, load average: 0.00, 0.01, 0.00

Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie

Cpu(s): 0.2%us, 0.1%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

Mem: 8059152k total, 5255384k used, 2803768k free, 148872k buffers

Swap: 0k total, 0k used, 0k free, 1151812k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

6267 root 20 0 8930m 2.9g 17m S 0.0 37.6 4:13.31 java

那么其余的0.9G內(nèi)存去哪了呢?

這時候就要介紹下JVM與Linux內(nèi)存的聯(lián)系了

當(dāng)Java程序啟動后,會根據(jù)Xmx為堆預(yù)申請一塊保留內(nèi)存,并不會直接使用,也不會占用物理內(nèi)存

然后申請(malloc之類的方法)Xms大小的虛擬內(nèi)存,但是由于操作系統(tǒng)的內(nèi)存管理是惰性的,有一個內(nèi)存延遲分配的概念。malloc雖然會分配內(nèi)存地址空間,但是并沒有映射到實際的物理內(nèi)存,只有當(dāng)對該地址空間賦值時,才會真正的占用物理內(nèi)存,才會影響RES的大小。

所以可能會出現(xiàn)進(jìn)程所用內(nèi)存大于當(dāng)前堆+非堆的情況。

比如說該Java程序在5分鐘前,有一定活動,占用了2.6G堆內(nèi)存(無論堆中的什么代),經(jīng)過GC之后,雖然堆內(nèi)存已經(jīng)被回收了,堆占用很低,但GC的回收只是針對Jvm申請的這塊內(nèi)存區(qū)域,并不會調(diào)用操作系統(tǒng)釋放內(nèi)存。所以該進(jìn)程的內(nèi)存并不會釋放,這時就會出現(xiàn)進(jìn)程內(nèi)存遠(yuǎn)遠(yuǎn)大于堆+非堆的情況。

至于Oracle文檔上說的,Jvm可能會向操作系統(tǒng)釋放內(nèi)存,經(jīng)過測試沒有發(fā)現(xiàn)釋放的情況。不過就算有主動釋放的情況,也不太需要我們程序關(guān)心了。

RES(Resident Set Size)是常駐內(nèi)存的意思,進(jìn)程實際使用的物理內(nèi)存

參考

總結(jié)

以上是生活随笔為你收集整理的java 物理内存_聊聊Java中的内存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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