记一次golang内存泄露
记一次golang内存泄露
最近在QA环境上验证功能时,发现机器特别卡,查看系统内存,发现可用(available)内存仅剩200多M,通过对进程耗用内存进行排序,发现有一个名为application-manager的容器服务的内存占用达到700多M,该服务使用Gin框架对外提供操作k8s资源的简单功能,解析客户端请求,并将结果返回给客户端。由于是测试环境,访问量极少,但内存一直只增不减,从最初的10M,一直增加到700多M,最终由于OOM而被重启(Pod)。
最初使用go pprof来尝试定位是否代码中存在如未释放的全局变量或存在goroutine泄露。初步定位后发现并没有goroutine泄露。/debug/pprof/allocs导出的svg文件参见这里:
# go tool pprof http://oms.qa.internal.hsmob.com/debug/pprof/allocs
Fetching profile over HTTP from http://oms.qa.internal.hsmob.com/debug/pprof/allocs
Saved profile in C:\Users\liuch\pprof\pprof.application-manager.alloc_objects.alloc_space.inuse_objects.inuse_space.005.pb.gz
File: application-manager
Type: alloc_space
Time: May 24, 2021 at 9:21am (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) web
内存占用图中唯一一个与自己的功能有关的代码就是setK8sEvent,至此可以初步怀疑问题所在。但问题点并不明确。另外在图中可以看到占用内存最多的函数是goLookupIpCNAMEOrder,该函数与域名查找有关,可能是建立链接前的步骤。
进入该容器(application-manager),查看底层链接情况,可以看到在该容器中建立了9492条TCP链接。至此已经找到问题根因,内存泄露的原因是没有及时关闭TCP,导致创建了大量socket,占用大量内存。
# ss -s
Total: 10215 (kernel 15097)
TCP: 9492 (estab 7953, closed 1537, orphaned 0, synrecv 0, timewait 1106/0), ports 0
Transport Total IP IPv6
* 15097 - -
RAW 0 0 0
UDP 0 0 0
TCP 7955 7952 3
INET 7955 7952 3
FRAG 0 0 0
在容器中使用ss -ntp命令进一步查看是创建了到哪些服务链接。最终发现创建了大量到elasticsearch 9200端口的链接,结合前面提到的setK8sEvent函数(该函数会将k8s事件发送给elasticsearch),基本可以确定是在读取es的数据之后,忘了执行resp.Body.Close()操作。
后记
代码中的确存在没有执行resp.Body.Close()的操作,修复之后发现内存占用正常。
总结
- 如果golang程序发现内存泄露,可以首先检查socket泄露。
记一次golang内存泄露的更多相关文章
- [golang]golang time.After内存泄露问题分析
无意中看到一篇文章说,当在for循环里使用select + time.After的组合时会产生内存泄露,于是进行了复现和验证,以此记录 内存泄露复现 问题复现测试代码如下所示: package mai ...
- 解Bug之路-记一次JVM堆外内存泄露Bug的查找
解Bug之路-记一次JVM堆外内存泄露Bug的查找 前言 JVM的堆外内存泄露的定位一直是个比较棘手的问题.此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤 ...
- 记一次Java的内存泄露分析
当前环境 jdk == 1.8 httpasyncclient == 4.1.3 代码地址 git 地址:https://github.com/jasonGeng88/java-network-pro ...
- 记一次调试python内存泄露的问题
转载:http://www.jianshu.com/p/2d06a1a01cc3 这两天由于公司需要, 自己编写了一个用于接收dicom文件(医学图像文件)的server. 经过各种coding-de ...
- golang kafka clinet 内存泄露问题处理
go 内存泄露 新版本服务跑上一天内存占用20g,显然是内存泄露 内存泄露的问题难在定位 技术上的定位 主要靠 pprof 生成统计文件 之前写web项目 基于net/http/pprof 可以看到运 ...
- 实战Go内存泄露【转】
最近解决了我们项目中的一个内存泄露问题,事实再次证明pprof是一个好工具,但掌握好工具的正确用法,才能发挥好工具的威力,不然就算你手里有屠龙刀,也成不了天下第一,本文就是带你用pprof定位内存泄露 ...
- Android开发笔记——常见BUG类型之内存泄露与线程安全
本文内容来源于最近一次内部分享的总结,没来得及详细整理,见谅. 本次分享主要对内存泄露和线程安全这两个问题进行一些说明,内部代码扫描发现的BUG大致分为四类:1)空指针:2)除0:3)内存.资源泄露: ...
- 【转】c++内存泄露检测,长文慎入!
原文网址:http://blog.csdn.net/zengraoli/article/details/8905334 关于内存泄露的,今天无意想到,网上找了一下 本篇blog附带的所有工具和代码 ...
- Java内存泄露原因详解
一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(He ...
随机推荐
- DBeaver、Navicat、MySQL高频报错及解决方法,此文持续更新
目录 第一坑,没有用管理员身份 第二坑,MySQL 服务无法启动 第三坑,报错:ERROR 1045 (28000): Access denied for user 'root'@'localhost ...
- JVMGC+Spring Boot生产部署和调参优化
一.微服务开发完成,IDEA进行maven clean和package 出现BUILD SUCCESS说明打包成功 二.要求微服务启动时,配置JVM GC调优参数 p.p1 { margin: 0; ...
- 使用Vanilla框架制作时间倒数器 ——JavaScript
一.制作时间倒数器要求以及思路: 1.首先创建三个输入字段,分别是小时,分钟和秒,以及"开始"按钮.输入的初始值必须为0h 5m 0s.当用户输入小时,分钟和秒并单击" ...
- JavaWeb 补充(Filter&Listener)
目录 Filter:过滤器 Listener:监听器 Filter:过滤器 1. 概念: * 生活中的过滤器:净水器,空气净化器,土匪. * web中的过滤器:当访问服务器的资源时,过 ...
- Palindromes UVA - 401
A regular palindrome is a string of numbers or letters that is the same forward as backward. For e ...
- UI自动化测试框架:PO模式+数据驱动
1. PO 设计模式简介 2. 工程结构说明 3. 工程代码实现 page 包 action 包 business_process 包 util 包 conf 包 test_data 目录 log 目 ...
- 488. Zuma Game
Think about Zuma Game. You have a row of balls on the table, colored red(R), yellow(Y), blue(B), gre ...
- 13- jmeter性能测试案例
配置原件 HTTP请求默认值 前置处理程序 定时器 取样器 后置处理器:正则表达式提取器 断言 监听器 性能测试流程 1.评估获取性能测试需求(访问量大,操作频繁) 2.确定性能测试目标 : 并发用户 ...
- Android最新敲诈者病毒分析及解锁(11月版)
一.样本信息 文件名称:久秒名片赞,(无需积分s)(2)(1)(1).apk 文件大小:1497829字节 文件类型:application/jar 病毒类型:Android.CtLocker 样本包 ...
- hdu2158 最短区间版大家来找碴
题意: 最短区间版大家来找碴 Problem Description 给定一个序列,有N个整数,数值范围为[0,N).有M个询问,每次询问给定Q个整数,可能出现重复值 ...