监控JVM的非堆内存使用情况

13 浏览
0 Comments

监控JVM的非堆内存使用情况

我们通常处理OutOfMemoryError问题是因为堆或permgen大小配置问题。

但JVM的所有内存并不都是permgen或堆。

就我所了解,它也可能与线程/堆栈、本机JVM代码等有关。

但是使用pmap命令,我可以看到该进程被分配了9.3G内存,其中有3.3G是堆外内存使用。

我想知道如何监视和调整这种额外的堆外内存消耗的可能性。

我没有使用直接的堆外内存访问(MaxDirectMemorySize默认为64m)。

上下文:负载测试

应用程序:Solr/Lucene服务器

操作系统:Ubuntu

线程数:700

虚拟化:vSphere(由我们运行,没有外部托管)

JVM版本:

java version "1.7.0_09"

Java(TM) SE Runtime Environment (build 1.7.0_09-b05)

Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)

调整配置:

-Xms=6g

-Xms=6g

-XX:MaxPermSize=128m

-XX:-UseGCOverheadLimit

-XX:+UseConcMarkSweepGC

-XX:+UseParNewGC

-XX:+CMSClassUnloadingEnabled

-XX:+OptimizeStringConcat

-XX:+UseCompressedStrings

-XX:+UseStringCache

内存映射:

https://gist.github.com/slorber/5629214

vmstat:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----

r b swpd free buff cache si so bi bo in cs us sy id wa

1 0 1743 381 4 1150 1 1 60 92 2 0 1 0 99 0

free:

total used free shared buffers cached

Mem: 7986 7605 381 0 4 1150

-/+ buffers/cache: 6449 1536

Swap: 4091 1743 2348

Top:

top - 11:15:49 up 42 days, 1:34, 2 users, load average: 1.44, 2.11, 2.46

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

Cpu(s): 0.5%us, 0.2%sy, 0.0%ni, 98.9%id, 0.4%wa, 0.0%hi, 0.0%si, 0.0%st

Mem: 8178412k total, 7773356k used, 405056k free, 4200k buffers

Swap: 4190204k total, 1796368k used, 2393836k free, 1179380k cached

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

17833 jmxtrans 20 0 2458m 145m 2488 S 1 1.8 206:56.06 java

1237 logstash 20 0 2503m 142m 2468 S 1 1.8 354:23.19 java

11348 tomcat 20 0 9184m 5.6g 2808 S 1 71.3 642:25.41 java

1 root 20 0 24324 1188 656 S 0 0.0 0:01.52 init

2 root 20 0 0 0 0 S 0 0.0 0:00.26 kthreadd

...

我们遇到的主要问题:

- 服务器具有8G的物理内存

- Solr的堆只占用了6G

- 有1.5G的交换空间

- Swappiness=0

- 堆的消耗似乎已经适当调整

- 在服务器上运行:只有Solr和一些监控工具

- 我们有正确的平均响应时间

- 有时会出现异常长的暂停,长达20秒

我猜这些暂停可能是堆交换导致的完全GC,对吗?

为什么会有这么多交换空间?

我甚至不确定是JVM使服务器交换还是有些隐藏的东西我看不见。也许是操作系统的页面缓存?但不确定为什么操作系统会创建导致交换的页面缓存条目。

我正在考虑测试一下一些流行的基于Java的存储/NoSQL(如ElasticSearch、Voldemort或Cassandra)中使用的mlockall技巧:查看Make JVM/Solr not swap, using mlockall

编辑:

在这里可以看到最大堆、已使用堆(蓝色)和已使用交换(红色)。它们似乎有一定的关联。

图片:https://i.stack.imgur.com/YFoWi.png

我可以通过Graphite看到定期发生很多ParNew GC。而且有一些CMS GC与图片中堆显著减少相对应。

这些暂停似乎与堆的减少没有相关性,但在10:00和11:30之间定期分布,所以可能与ParNew GC有关。

在负载测试期间,我可以看到一些磁盘活动和一些交换IO活动,当测试结束时,活动非常平静。

0