You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes Pod内gRPC服务内存分配失败问题咨询

Kubernetes中gRPC服务内存分配异常问题

我在Kubernetes中部署了一个gRPC服务,所有内存分配均通过tcmalloc完成,但Pod频繁出现内存不足问题。以下是堆栈追踪信息:

terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create
*** Aborted at 1668932192 (unix time) try "date -d @1668932192" if you are using GNU date ***
PC: @                0x0 (unknown)
*** SIGABRT (@0x1) received by PID 1 (TID 0x7f2e45bd3700) from PID 1; stack trace: ***
    @     0x7f2e4c7d63c0 (unknown)
    @     0x7f2e4c4a918b gsignal
    @     0x7f2e4c488859 abort
    @     0x7f2e4c8a1951 (unknown)
    @     0x7f2e4c8ad47c (unknown)
    @     0x7f2e4c8ad4e7 std::terminate()
    @     0x7f2e4c8ad799 __cxa_throw
    @     0x7f2e4c8a4366 std::__throw_length_error()
    @     0x7f2e4c9459fc std::__cxx11::basic_string<>::_M_create()
    @     0x561821534960 __gnu_cxx::new_allocator<>::construct<>()
    @     0x56182153390b metrics::ReadReporter::Report()
    @     0x56182125cb54 std::_Function_handler<>::_M_invoke()
    @     0x56182151f2aa std::_Function_handler<>::_M_invoke()
    @     0x56182154092e std::_Function_handler<>::_M_invoke()
    @     0x56182153f5e5 file::HttpRequest::Invoke()
    @     0x7f2e4c8d9d84 (unknown)
    @     0x7f2e4c7ca609 start_thread
    @     0x7f2e4c585293 clone
    @                0x0 (unknown)
terminate called recursively
terminate called recursively
external/com_google_tcmalloc/tcmalloc/tcmalloc_policy.h:102] Unable to allocate (new failed) 8111000728417 @ 0x561822037742 0x56182200fc67 0x561822003b0f 0x561821534960 0x56182153390b 0x56182125cb54 0x56182125d10a 0x56182151f2aa 0x56182154092e 0x56182153f5e5 0x561821545432 0x7f2e4c8d9d84
See https://github.com/google/tcmalloc/tree/master/docs/stats.md for an explanation of this page

我已为该服务配置了就绪探针和存活探针,仅通过一个线程监听并响应TCP请求。我的疑问如下:

  1. 为何Pod未触发OOM(堆栈中已显示抛出SIGABRT)并被Kubernetes重启?
  2. 我知道可通过增加容器内存配额、添加限流来临时解决,但这是否是最优方案?

问题解答

1. 为何未触发OOM而是抛出SIGABRT?

Kubernetes的OOM Killer触发的前提是容器进程尝试申请内存时,节点的cgroup内存限制被耗尽,此时内核会发送SIGKILL终止进程。但你的情况是应用本身主动抛出异常并触发了SIGABRT:

  • 从堆栈看,std::length_error是在metrics::ReadReporter::Report()中创建std::string时抛出的,原因是尝试分配的内存大小异常(8111000728417字节,约7.37TB),这个数值明显超出合理范围,大概率是代码中存在逻辑错误(比如未初始化的变量作为字符串长度传入)。
  • tcmalloc在尝试分配这个超大内存块失败后,C++标准库抛出了未捕获的异常,最终触发std::terminate()调用abort()发送SIGABRT终止进程。此时容器的内存使用可能还没达到Kubernetes配置的内存配额上限,所以OOM Killer没有被触发。

2. 增加配额或限流是否是最优方案?

不是,这只是临时规避手段,最优方案是修复代码中的根本问题:

  • 定位到metrics::ReadReporter::Report()方法,检查其中创建std::string的逻辑:是否存在计算字符串长度时的溢出、未初始化变量、错误的数值转换(比如将指针值当作长度)等问题。
  • 异常的分配大小8111000728417是一个极大的数,几乎可以肯定是代码逻辑错误导致的非法长度值,而非正常的内存需求增长。
  • 即使增加内存配额,这种非法的超大内存分配请求依然会失败,最终还是会触发SIGABRT;限流只能降低触发频率,但无法解决根源问题。

建议先排查并修复metrics::ReadReporter::Report()中的字符串创建逻辑,再结合tcmalloc的内存统计工具分析正常业务的内存使用情况,按需调整配额或添加限流策略。


内容的提问来源于stack exchange,提问作者Tinyden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 07:10:11