最近看到一个问题,说现场遇到了内存耗光的情况,耗内存的程序是一个小程序。简直是不可思议!根据AI的提示,找到了THP这个配置。当系统全局启用THP(enabled=always)时,内核会自动将4KB小页合并为2MB大页,若应用频繁分配小块内存(如XML解析时的字符串、节点对象),会因大页内部碎片导致内存膨胀,实际仅需几KB的对象会占用整个2MB大页,造成“分配8KB却消耗2MB”的极端浪费情况。所以这个怀疑性更大。看了一下Redhat的发行版本的编译配置,默认是always:/boot/config-4.18.0-240.10.1.el8_3.x86_64:CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
系统起来之后的参数配置输出:
[root@ABC~]# cat /sys/kernel/mm/transparent_hugepage/enabled[always] madvise never
如果想要修改这个配置,而且是系统启动时生效,需要在cmdline里加内核启动参数:
transparent_hugepage=never
如果想实时生效,可以echo值到这个配置文件。但是之前已申请分配的大页仍然还会在系统里。
下面这个网页里,还有一些其他的信息,有兴趣的可以看看:https://access.redhat.com/solutions/46111。如果程序在释放内存的时候,主动调用glibc的接口malloc_trim,将内存主动返回给系统,可以缓解这个问题。
系统内存耗光之后,就所有的情况都有可能出现了,比如新起的ssh会话没有反应,scp传输文件失败。