linux – 在java进程中消耗内存的是什么?

linux – 在java进程中消耗内存的是什么?,第1张

概述我们正在尝试在中等负载下研究 java进程内存使用情况. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 12663 test 20 0 8378m 6.0g 4492 S 43 8.4 162:29.95 java 如你所见,我们有6Gb的常驻内存.现在有趣的部分是:使用这些参数执行该过程 我们正在尝试在中等负载下研究 java进程的内存使用情况.
PID   USER    PR  NI  VIRT  RES  SHR S %cpu %MEM    TIME+  COMMAND  12663 test    20   0 8378m 6.0g 4492 S   43  8.4 162:29.95 java

如你所见,我们有6Gb的常驻内存.现在有趣的部分是:使用这些参数执行该过程:

> -Xmx2048m
> -xms2048m
> -XX:NewSize = 512m
> -XX:MaxDirectMemorySize = 256m
> ……其他一些GC和东西

看看这些设置和实际内存使用情况,我们偶然发现我们期望这个过程使用的内容与实际使用内容的区别.

通常我们的内存问题通过分析堆转储来解决,但在这种情况下,我们的内存被用在堆外的某个地方.

问题:
尝试找出如此高内存使用率的原因是什么?
哪些工具可以帮助我们确定在该过程中使用内存的内容?

编辑0

看起来这不是一个堆相关的问题,因为我们仍然有相当大的空间:

jmap -heap 12663

结果(编辑以节省空间)

Heap Configuration:MinHeapFreeRatio = 40MaxHeapFreeRatio = 70MaxHeapSize      = 2147483648 (2048.0MB)NewSize          = 536870912 (512.0MB)MaxNewSize       = 536870912 (512.0MB)oldSize          = 1610612736 (1536.0MB)NewRatio         = 7SurvivorRatio    = 8PermSize         = 21757952 (20.75MB)MaxPermSize      = 85983232 (82.0MB)New Generation: 45.7% usedEden Space: 46.3% usedFrom Space: 41.4% usedTo Space: 0.0% usedconcurrent mark-sweep generation: 63.7% usedPerm Generation: 82.5% used

编辑1

使用pmap我们可以看到有相当多的64Mb分配:

pmap -x 12663 | grep rwx | sort -n -k3 | less

结果是:

... a lot more of these 64Mb chunks00007f32b8000000       0   65508   65508 rwx--    [ anon ] <- what are these?00007f32ac000000       0   65512   65512 rwx--    [ anon ]00007f3268000000       0   65516   65516 rwx--    [ anon ]00007f3324000000       0   65516   65516 rwx--    [ anon ]00007f32c0000000       0   65520   65520 rwx--    [ anon ]00007f3314000000       0   65528   65528 rwx--    [ anon ] 00000000401cf000       0  241904  240980 rwx--    [ anon ] <- Direct memory ?000000077ae00000       0 2139688 2139048 rwx--    [ anon ] <- Heap ?

那么如何找出那些64Mb的块是什么?什么在使用它们?它们中包含哪些数据?

谢谢

解决方法 该问题可能与此 glibc issue有关.

基本上,当你有多个线程分配内存时,glibc会扩大可用竞技场的数量来进行分配,以避免锁争用.竞技场是64Mb大.上限是创建核心竞技场的8倍.当线程访问已经锁定的竞技场时,Arenas将按需创建,以便随着时间的推移而增长.

在Java中,您可以使用线程,这可以很快导致创建许多竞技场.并且分配遍布这些领域.最初,每个64Mb竞技场只是映射未经注册的内存,但是当您进行分配时,您开始为它们使用实际内存.

您的pmap可能具有与以下类似的列表.注意324K 65212K = 65536K,560K 64976K == 65536K,620K 64916K == 65536K.也就是说,它们总计达到64Mb.

00007f4394000000    324K rw---    [ anon ]00007f4394051000  65212K -----    [ anon ]00007f4398000000    560K rw---    [ anon ]00007f439808c000  64976K -----    [ anon ]00007f439c000000    620K rw---    [ anon ]00007f439c09b000  64916K -----    [ anon ]

至于变通方法:BUG提到了一些你可以设置的环境参数来限制竞技场的数量,但你需要一个足够高的glibc版本.

总结

以上是内存溢出为你收集整理的linux – 在java进程中消耗内存的是什么?全部内容,希望文章能够帮你解决linux – 在java进程中消耗内存的是什么?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1045184.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存