让我先从图片开始:
这是我们的备份 Tomcat 服务器的内存使用情况。它只是挂在那里,每隔几秒钟处理一次简单的健康检查请求,并等待主服务器崩溃以承担负载。而且它的内存使用量仍在增长。主服务器的内存也在增长。迟早,Nagios 会开始发送有关内存和交换使用情况的短信和电子邮件。
两台服务器都运行 CentOS 7、内核 3.10、Java 1.7 和 Tomcat 7。
即使我停止使用 Tomcat 服务器systemctl stop tomcat
,内存仍然处于使用状态。
我发现释放内存的唯一方法是sync && echo 3 > /proc/sys/vm/drop_caches
。因此,解决方法是将其放入cronjob
。但我想找到一个合适的解决方案。
我找到了这个线关于类似的问题,它提到设置MALLOC_ARENA_MAX
为 4(而其他一些线程建议设置为 1),我还发现一个线程说它应该与MALLOC_CHECK_
环境变量一起工作。但事实并非如此。这就是您在图表右侧看到的内容。
如果我看广告已用内存,保持在 600 MB 左右,并且使用的非堆内存为70 MB。
您知道是什么原因造成的吗?如何解决?我再说一遍,Tomcat 停止后内存没有释放,因此我认为我们的应用程序没有内存泄漏。
# free -m
total used free shared buffers cached
Mem: 64268 4960 59307 64 0 135
-/+ buffers/cache: 4824 59443
Swap: 2047 0 2047
# ps -eo rss | awk '{sum += $1}; END {print sum/1024/1024}'
2.54199
今天早上更新,cronjob 释放内存 9 小时后:
# free -h
total used free shared buffers cached
Mem: 62G 13G 48G 80M 0B 77M
-/+ buffers/cache: 13G 48G
Swap: 2,0G 4K 2,0G
# ps -eo vsize | awk '{sum += $1}; END {print sum/1024/1024}'
25.8389
# ps -eo rss | awk '{sum += $1}; END {print sum/1024/1024}'
1.24232
# ps -eo pmem,rss,vsize,args | grep tomcat
1.7 1158608 22684408 java -classpath /usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat -Dcatalina.home=/usr/share/tomcat -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat/temp -Djava.util.logging.config.file=/usr/share/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start
这变得非常奇怪。正在运行的程序每隔几秒钟keepalived
就会向我们应用程序的健康检查功能发送 HTTP 请求curl
。如果我停止keepalived
,内存就会停止增长。如果我curl
从同一台机器上的 bash 无限循环发送相同的请求,内存就会再次开始增长。即使我将请求发送到返回 404 的 URL。如果我在不同的机器上启动相同的循环(所以不是从本地主机),内存就没问题。
# slabtop -o
Active / Total Objects (% used) : 244359165 / 244369016 (100,0%)
Active / Total Slabs (% used) : 5810996 / 5810996 (100,0%)
Active / Total Caches (% used) : 70 / 99 (70,7%)
Active / Total Size (% used) : 45770306,72K / 45772288,52K (100,0%)
Minimum / Average / Maximum Object : 0,01K / 0,19K / 8,00K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
243660018 243660018 11% 0,19K 5801429 42 46411432K dentry
143872 141868 98% 0,03K 1124 128 4496K kmalloc-32
118150 118150 100% 0,02K 695 170 2780K fsnotify_event_holder
87040 87040 100% 0,01K 170 512 680K kmalloc-8
80448 79173 98% 0,06K 1257 64 5028K kmalloc-64
56832 56832 100% 0,02K 222 256 888K kmalloc-16
31926 31926 100% 0,08K 626 51 2504K selinux_inode_security
31140 31140 100% 0,11K 865 36 3460K sysfs_dir_cache
15795 14253 90% 0,10K 405 39 1620K buffer_head
15008 14878 99% 1,00K 469 32 15008K xfs_inode
14616 13365 91% 0,19K 348 42 2784K kmalloc-192
11961 11714 97% 0,58K 443 27 7088K inode_cache
10048 9108 90% 0,06K 157 64 628K anon_vma
9664 9480 98% 0,12K 302 32 1208K kmalloc-128
9287 7954 85% 0,21K 251 37 2008K vm_area_struct
8624 8624 100% 0,07K 154 56 616K Acpi-ParseExt
7264 7063 97% 0,25K 227 32 1816K kmalloc-256
5908 5908 100% 0,57K 211 28 3376K radix_tree_node
5304 5304 100% 0,04K 52 102 208K Acpi-Namespace
4620 4620 100% 0,09K 110 42 440K kmalloc-96
3744 3586 95% 1,00K 117 32 3744K kmalloc-1024
3458 3458 100% 0,30K 133 26 1064K nf_conntrack_ffffffff819a29c0
3360 3067 91% 0,50K 105 32 1680K kmalloc-512
3108 3108 100% 0,38K 74 42 1184K blkdev_requests
2975 2975 100% 0,05K 35 85 140K shared_policy_node
2520 2368 93% 0,64K 105 24 1680K proc_inode_cache
1560 1560 100% 0,81K 40 39 1280K task_xstate
1300 1300 100% 0,15K 50 26 200K xfs_ili
1272 1272 100% 0,66K 53 24 848K shmem_inode_cache
1176 1176 100% 1,12K 42 28 1344K signal_cache
1024 1024 100% 2,00K 64 16 2048K kmalloc-2048
975 975 100% 0,62K 39 25 624K sock_inode_cache
900 900 100% 0,44K 25 36 400K scsi_cmd_cache
864 864 100% 0,25K 27 32 216K tw_sock_TCPv6
737 644 87% 2,84K 67 11 2144K task_struct
720 672 93% 2,00K 45 16 1440K TCPv6
704 704 100% 0,18K 16 44 128K xfs_log_ticket
665 665 100% 0,23K 19 35 152K cfq_queue
646 646 100% 0,94K 19 34 608K RAW
640 640 100% 0,39K 16 40 256K xfs_efd_item
624 624 100% 0,10K 16 39 64K blkdev_ioc
624 624 100% 0,20K 16 39 128K xfs_btree_cur
578 578 100% 0,12K 17 34 68K fsnotify_event
555 555 100% 2,06K 37 15 1184K sighand_cache
528 528 100% 0,48K 16 33 256K xfs_da_state
512 512 100% 0,06K 8 64 32K kmem_cache_node
512 512 100% 1,00K 16 32 512K UDP
465 465 100% 2,06K 31 15 992K idr_layer_cache
450 450 100% 0,62K 18 25 288K files_cache
答案1
根据slabtop
输出,我认为某些东西正在某处添加大量临时文件,然后删除它们。另一个问题是,某些进程仍持有已删除文件的文件句柄,因此文件不会从目录项中释放。由于文件被标记为已删除,因此您无法使用常规ls
和类似命令找到它们。
可能是 curl 或您调用它的脚本。查看lsof -n | grep deleted
是否有大量已删除的条目,然后从那里找到罪魁祸首。