首页 > 系统相关 >K8S集群问题:案例一:Java调用Glibc2.28-69内存分配器无法限制虚拟内存VIRT问题

K8S集群问题:案例一:Java调用Glibc2.28-69内存分配器无法限制虚拟内存VIRT问题

时间:2024-04-24 21:45:29浏览次数:12  
标签:容器 java Glibc2.28 线程 内存 分配器 虚拟内存

一、问题描述

1、背景:

租户反馈,Apr 7 11:22容器出现夯死现象, 容器部署的单个java进程;

宿主机上,top显示的容器进程virt内存持续增长32G,目前messages日志没有看到oom的记录,基本是。租户其他bc7、8系统上有添加参数MALLOC_ARENA_MAX进行限制,基本维持在16G左右,目前bcoe21.10系统配置参数MALLOC_ARENA_MAX可能没有生效,导致宿主机内存碎片问题;

2、容器内部java进程的虚拟内存异常增长30g-60g

 

二、排查过程

1、租户三台测试K8S节点主机使用MALLOC_ARENA_MAX=4限制内存可分配块的创建、合并、回收,传参给容器,由于java线程占用64M内存无法及时释放,导致主内存区块被占满,后续java线程请求不断从其他内存块分配内存,导致内存持续增长,尝试解决办法:调整MALLOC_ARENA_MAX=1和glibc版本;

 

ii.三节点调整MALLOC_ARENA_MAX=1

export MALLOC_ARENA_MAX=1

参考:
https://blog.csdn.net/m0_38017860/article/details/122192243

 

查看虚拟内存堆栈调用详情:pmap -x 进程ID

发现有61880KB的匿名线程的内存调用

iii.结果

两台测试机156是2.28-84和157是2.28-93,内存分配参数malloc_arena_max=1可以做到局部内存块回收,容器虚拟内存至17.3G左右,但是三台测试机均出现javacore问题;

2、测试发现glibc2.28-69glibc2.28-93glibc2.28-97内存分配器无法做到有效限制VIRT虚拟内存,尝试调整新的tcmalloct内存分配器;

i.安装方法:

 

 

ii.k8s节点,调整容器java配置

涉及应用容器java配置的调整,用于调用libtcmalloct库;

iii.验证libtcmalloct内存分配器库的调用情况

 

pmap -x java进程id | grep ‘libtcmalloc.so‘

iv.三台测试机的调整详情


 

 

v.结果

经过一天的观察, 调整内存分配器后,目前java容器内存稳定17.3g,期间客户有调整jdk版本,经过业务压测没有出现javacore的问题;

三、根因

这种情况是由于业务量较大,导致glibc可分配主内存空间数占满,后续申领主内存块时,导致MALLOC_ARENA_MAX 限制的可分配最大内存空间数失效;

那么按照测试参数1是否可以解释放堆顶层线程占用内存块?有明显的效果,可以做到部分内存块回收;

通过tcmalloc内存分配器,来解决后续glibc申请主内存块不足的问题,可以做到有效回收主内存块空间,维持17.3G。

主要问题是由于客户的jdk版本问题,jdk版本代码存在内存泄漏导致匿名内存块的持续消耗。由于栈顶java线程申领的主内存块没有释放变为匿名内存,持续占用主内存空间,导致后续java线程没有主内存块可以申领,后续非主内存持续消耗,top中查看业务线程的虚拟内存VIRT的异常消耗(32G~60G),通过安装tcmalloct内存分配器,可以有效的限制java线程的VIRT申领维持在17.3G左右,后续客户调整jdk版本,观察容器加载业务后,目前java容器没有出现javacore的现象;

 

标签:容器,java,Glibc2.28,线程,内存,分配器,虚拟内存
From: https://www.cnblogs.com/gkhost/p/18156421

相关文章

  • 在Linux中,虚拟内存和交换空间作用是什么?
    在Linux系统中,虚拟内存和交换空间是用于扩展物理内存(RAM)容量的两种机制。它们允许系统在物理内存不足时继续运行程序和处理数据,从而提高了系统的可用性和稳定性。1.虚拟内存(VirtualMemory)概念:虚拟内存是一种内存管理技术,它使得系统可以访问比物理内存更多的内存空间。虚拟......
  • 虚拟内存知识详解
    虚拟内存单片机的CPU是直接操作内存的「物理地址」在这种情况下,要想在内存中同时运行两个程序是不可能的操作系统是如何解决这个问题呢?关键的问题是这两个程序都引用了绝对物理地址,而这正是我们最需要避免的。可以把进程所使用的地址「隔离」开来,即让操作系统为每......
  • linux物理内存,虚拟内存的获取
    使用文件流的方式,解析   cat/proc/meminfo 文件里面的数据 #include<iostream>#include<fstream>#include<sstream>#include<string>#include<unordered_map>#include<map>structBASE_INFO_S{unsignedlonglongMemTot......
  • 在Linux中,什么是虚拟内存?它是如何工作的?
    虚拟内存是一种内存管理技术,它允许操作系统使用硬盘空间来模拟额外的内存资源。虚拟内存的工作原理涉及以下几个关键概念:地址空间:每个进程拥有自己的虚拟地址空间,这个空间对于进程来说是一致的和私有的。虚拟地址空间的大小通常远大于物理内存的大小。分页机制:操作系统将物理......
  • 每个程序员都应该了解的内存知识(三): 虚拟内存
    虚拟内存概念wiki解释它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上物理内存通常被分隔成多个内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。阅读链接虚拟内存篇(原文地址)详解内存映射(做的图非常好,一定要重点看一看)MM......
  • Lec3 Lec4: 虚拟内存和RISC-V寄存器
    虚拟内存使用虚拟内存主要为了实现隔离内存隔离,所有程序指令存放在一个物理内存上,如果一个指令的操作位刚好是另一个指令的地址,那么会造成指令的丢失为了解决这个问题使用地址空间地址空间为每一个指令程序分配自己的地址空间,每个指令程序只能在自己的地址空间上操作。我们需......
  • 批处理脚本来将 Windows 10 的虚拟内存设置为自动管理所有驱动器的分页文件大小
    批处理脚本来将Windows10的虚拟内存设置为自动管理所有驱动器的分页文件大小:CopyCode@echooffREM将所有驱动器的分页文件大小设置为自动管理REM禁用虚拟内存wmiccomputersystemwherename="%computername%"setAutomaticManagedPagefile=Falsewmicpagefilesetw......
  • nand2tetris_选择器和分配器
    布尔函数基础布尔运算符AndOrNot布尔函数布尔函数类比数学里的方程,可以认为自变量的取值只有0和1两种,也就是说,布尔函数是可以枚举的,即真值表。布尔函数(可能需要化简)可以认为是等价于真值表。更多时候,往往需要从真值表(结果,或者说需求)推导出布尔函数,再化简设计出最优电......
  • 云服务centos7 增加虚拟内存
    1、查看磁盘使用情况free-h而Mem就表示购买阿里云时候的内存,我们能够看到只有3.9G,并且已经使用了3.7G。 2、添加Swap分区使用dd命令创建名为swapfile的swap交换文件(文件名和目录任意):ddif=/dev/zeroof=/var/swapfilebs=1024count=4194304dev/zero是Linux的一种特殊字......
  • 服务器分配虚拟内存
    1.打开终端,输入命令sudoswapon-s查看当前交换分区情况。2.如果没有交换分区,则需要创建一个交换分区。可以通过GParted等工具进行创建,也可以通过命令sudoddif=/dev/zeroof=/swapfilebs=1Mcount=2048创建一个大小为2GB的交换文件。3.设置交换文件权限:sudochmod600/sw......