我联系上了WCS的值班人,将我们遇到的问题和他们描述了一下,他们回复我们,会在他们本地执行下写入操作的压测,看看能不能复现我们的问题 。
既然等待他们的反馈还需要时间,我们就准备先自己琢磨下原因 。
「我将怀疑的目光停留在了直接内存上,怀疑是由于接口调用量过大,客户端对nio使用不当,导致使用ByteBuffer申请过多的直接内存 。」
?沙箱环境复现为了能还原当时的故障场景,我在沙箱环境申请了一台压测机器,来确保和线上环境一致 。
「画外音:最终的结果证明,这一个先入为主的思路导致排查过程走了弯路 。在问题的排查过程中,用合理的猜测来缩小排查范围是可以的,但最好先把每种可能性都列清楚,在发现自己深入某个可能性无果时,要及时回头仔细审视其他可能性 。」
?
「首先我们先模拟内存溢出的情况(大量调用接口):」
我们让脚本继续推送数据,调用我们的接口,我们持续观察内存占用 。
当开始调用后,内存便开始持续增长,并且看起来没有被限制住(没有因为限制触发Full GC) 。
文章插图
「接着我们来模拟下平时正常调用量的情况(正常量调用接口):」
我们将该接口平时正常的调用量(比较小,且每10分钟进行一次批量调用)切到该压测机器上,得到了下图这样的老生代内存和物理内存趋势:
文章插图
文章插图
「问题来了:为何内存会不断往上走吃满内存呢?」
当时猜测是由于JVM进程并没有对于直接内存大小进行限制(-XX:MaxDirectMemorySize),所以堆外内存不断上涨,并不会触发FullGC操作 。
「上图能够得出两个结论:」
- 在内存泄露的接口调用量很大的时候,如果恰好堆内老生代等其他情况一直不满足FullGC条件,就一直不会FullGC,直接内存一路上涨 。
- 而在平时低调用量的情况下, 内存泄漏的比较慢,FullGC总会到来,回收掉泄露的那部分,这也是平时没有出问题,正常运行了很久的原因 。
结果发现,进程占用的物理内存依然会不断上涨,超出了我们设置的限制,“看上去”配置似乎没起作用 。
这让我很讶异,难道JVM对内存的限制出现了问题?
「到了这里,能够看出我排查过程中思路执着于直接内存的泄露,一去不复返了 。」
?直接内存分析为了更进一步的调查清楚直接内存里有什么,我开始对直接内存下手 。由于直接内存并不能像堆内存一样,很容易的看出所有占用的对象,我们需要一些命令来对直接内存进行排查,我有用了几种办法,来查看直接内存里到底出现了什么问题 。
「画外音:我们应该相信JVM对内存的掌握,如果发现参数失效,多从自己身上找原因,看看是不是自己使用参数有误 。」
?
查看进程内存信息 pmappmap - report memory map of a process(查看进程的内存映像信息)
pmap命令用于报告进程的内存映射关系,是linux调试及运维一个很好的工具 。
pmap -x pid 如果需要排序 | sort -n -k3**
执行后我得到了下面的输出,删减输出如下:..00007fa2d4000000 8660 8660 8660 rw--- [ anon ]00007fa65f12a000 8664 8664 8664 rw--- [ anon ]00007fa610000000 9840 9832 9832 rw--- [ anon ]00007fa5f75ff000 10244 10244 10244 rw--- [ anon ]00007fa6005fe000 59400 10276 10276 rw--- [ anon ]00007fa3f8000000 10468 10468 10468 rw--- [ anon ]00007fa60c000000 10480 10480 10480 rw--- [ anon ]00007fa614000000 10724 10696 10696 rw--- [ anon ]00007fa6e1c59000 13048 11228 0 r-x-- libjvm.so00007fa604000000 12140 12016 12016 rw--- [ anon ]00007fa654000000 13316 13096 13096 rw--- [ anon ]00007fa618000000 16888 16748 16748 rw--- [ anon ]00007fa624000000 37504 18756 18756 rw--- [ anon ]00007fa62c000000 53220 22368 22368 rw--- [ anon ]00007fa630000000 25128 23648 23648 rw--- [ anon ]00007fa63c000000 28044 24300 24300 rw--- [ anon ]00007fa61c000000 42376 27348 27348 rw--- [ anon ]00007fa628000000 29692 27388 27388 rw--- [ anon ]00007fa640000000 28016 28016 28016 rw--- [ anon ]00007fa620000000 28228 28216 28216 rw--- [ anon ]00007fa634000000 36096 30024 30024 rw--- [ anon ]00007fa638000000 65516 40128 40128 rw--- [ anon ]00007fa478000000 46280 46240 46240 rw--- [ anon ]0000000000f7e000 47980 47856 47856 rw--- [ anon ]00007fa67ccf0000 52288 51264 51264 rw--- [ anon ]00007fa6dc000000 65512 63264 63264 rw--- [ anon ]00007fa6cd000000 71296 68916 68916 rwx-- [ anon ]00000006c0000000 4359360 2735484 2735484 rw--- [ anon ]
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 皇菊花茶的功效与禁忌,菊花茶的禁忌与功效作用
- 监控Redis?使用Grafana的Source插件轻松搞定
- 大浪淘沙的古诗原文 浪淘沙借问长江与海水古诗
- 荀攸是荀彧的什么人 荀彧为曹操出的第一个计谋是
- 房子大了,设备多了,家里的WiFi网络该怎么优化?
- 安史之乱有多吓人 安禄山怎么死的(安禄山叛乱为什么失败)
- 在日本的中国文物 日本有哪些中国失传的古籍
- 汉朝的都城分别在哪里 汉朝首都在哪个城市
- 红楼梦中的袭人姓什么? 红楼梦袭人名字含义
- 赌书消得泼茶香当时只道是寻常中的典故出自哪位文人 赌书消得泼茶香,只道当时是寻常