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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 进程占用 VIRT 虚拟内存超高的问题研究

發(fā)布時間:2024/10/12 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 进程占用 VIRT 虚拟内存超高的问题研究 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

1. 現(xiàn)象

最近發(fā)現(xiàn)線上機器 java 8 進程的 VIRT 虛擬內存使用達到了 50G+,如下圖所示:

2. 不管用的 -Xmx

首先第一想到的當然使用 java 的 -Xmx 去限制堆的使用。但是無論怎樣設置,都沒有什么效果。沒辦法,只好開始苦逼的研究。

3. 什么是 VIRT

現(xiàn)代操作系統(tǒng)里面分配虛擬地址空間操作不同于分配物理內存。在64位操作系統(tǒng)上,可用的最大虛擬地址空間有16EB,即大概180億GB。那么在一臺只有16G的物理內存的機器上,我也能要求獲得4TB的地址空間以備將來使用。例如:

void *mem = mmap(0, 4ul * 1024ul * 1024ul * 1024ul * 1024ul,PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,-1, 0); 當使用 mmap 并設置 MAP_NORESERVE 標志時,并不會要求實際的物理內存和swap空間存在。所以上述代碼可以在top中看到使用了 4096g 的 VIRT 虛擬內存,這當然是不可能的,它只是表示使用了 4096GB 的地址空間而已。

4. 為什么會用這么多地址空間

那 Java 程序為什么會使用這么多的地址空間呢?使用“pmap -x”來查看一下:

00007ff638021000 65404 0 0 ----- [ anon ] 00007ff63c000000 132 36 36 rw--- [ anon ] 00007ff63c021000 65404 0 0 ----- [ anon ] 00007ff640000000 132 28 28 rw--- [ anon ] 00007ff640021000 65404 0 0 ----- [ anon ] 00007ff644000000 132 8 8 rw--- [ anon ] 00007ff644021000 65404 0 0 ----- [ anon ] 00007ff648000000 184 184 184 rw--- [ anon ] 00007ff64802e000 65352 0 0 ----- [ anon ] 00007ff64c000000 132 100 100 rw--- [ anon ] 00007ff64c021000 65404 0 0 ----- [ anon ] 00007ff650000000 132 56 56 rw--- [ anon ] 00007ff650021000 65404 0 0 ----- [ anon ] 00007ff654000000 132 16 16 rw--- [ anon ] 00007ff654021000 65404 0 0 ----- [ anon ] … 發(fā)現(xiàn)有很多奇怪的64MB的內存映射,查資料發(fā)現(xiàn)這是 glibc 在版本 2.10 引入的 arena 新功能導致。CentOS 6/7 的 glibc 大都是 2.12/ 2.17 了,所以都會有這個問題。這個功能對每個線程都分配一個分配一個本地arena來加速多線程的執(zhí)行。 在 glibc 的 arena.c 中使用的 mmap() 調用就和之前的示例代碼類似: p2 = (char *)mmap(aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0) 之后,只有很小的一部分地址被映射到了物理內存中: mprotect(p2, size, PROT_READ | PROT_WRITE) 因此在一個多線程程序中,會有相當多的 64MB 的 arena 被分配。這個可以用環(huán)境變量 MALLOC_ARENA_MAX 來控制。在64位系統(tǒng)中的默認值為 128。

5. Java 的特殊性

Java 程序由于自己維護堆的使用,導致調用 glibc 去管理內存的次數(shù)較少。更糟的是 Java 8 開始使用 metaspace 原空間取代永久代,而元空間是存放在操作系統(tǒng)本地內存中,那線程一多,每個線程都要使用一點元空間,每個線程都分配一個 arena,每個都64MB,就會導致巨大的虛擬地址被分配。

6. 結束語

總結一下:

  • VIRT高是因為分配了太多地址空間導致。
  • 一般來說不用太在意VIRT太高,因為你有16EB的空間可以使用。
  • 如果你實在需要控制VIRT的使用,設置環(huán)境變量MALLOC_ARENA_MAX,例如hadoop推薦值為4,因為YARN使用VIRT值監(jiān)控資源使用。

轉載于:https://www.cnblogs.com/seasonsluo/p/java_virt.html

總結

以上是生活随笔為你收集整理的Java 进程占用 VIRT 虚拟内存超高的问题研究的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。