环境

go1.16,sarama最新版本,gorilla/websocket最新版

功能

一个简单的服务,主要功能就是前端通过websocket连接我的go服务,会传入一个kafka的topic名字,我根据这个名字去连接kafka拿数据然后中间做一些处理再返回给前端,老板喊在这之间加一个缓存,即每一个topic都会拥有一份缓存,前端请求数据的时候都直接从该缓存拿数据,然后一个缓存只会与kafka建立一个连接,然后用一个goroutine去持续更新该缓存,前端拿数据的时候永远只拿缓存最新的一条数据,并且每隔一分钟会讲缓存内的内容写入到文件中进行持久化,于是现在的逻辑就变成了每当一个ws客户端来请求kafka数据,我都会根据topic名字做判断,如果该topic的缓存已经存在(有一个全局变量map[topic]*cache记录了当前有哪些缓存)则直接返回该topic的缓存给该客户端对象然后开始消费数据,如果没有则会去指定的目录下查找是否存在该topic的文件,有的话就加载进内存生成一个缓存对象然后将其指针给客户端,并在之前的map中记录该缓存的指针。
功能就是这样,现在遇到的问题就是我现在有一个缓存文件大概是400mb,每次系统刚启动,内存占用2mb左右,然后当客户端第一次请求该topic的数据,除了加载到内存中的400mb空间,内存会不停的上升,任务管理器里变化一次五六mb左右,根据缓存中每一条数据的大小好像不一样(暂时不确定),然后会上涨到一个阈值被强制gc回收部分空间然后又继续上升,当客户端断开连接后等待大概几分钟内存开始1mb左右的速度开始下降,但是始终没法降到理论上的400兆左右
,总是降到比理论值多接近200兆的程度就停下来)然后客户端再次请求该数据内存就又开始上涨,一直这样往复。
我为了排查具体问题,用pprof工具看了一下heap和allocs的情况,显示的内存基本上都是sarama的一个叫做responsereceiver方法占用的,而且运行过程(内存上升)中也没有发现有其他占用内存的地方,没有发现特别有价值的问题,我就开始采取注释一部分代码的方式来调试

最后测试出来的情况如下:

1、客户端请求数据,但是我不加载文件中的数据,直接连接kafka向缓存中写输入然后客户端从缓存拿数据内存依旧会保持一个速度上升;
2、客户端请求数据,并且加载文件中的数据,情况同1(这也是我需要实现的情况)
3、客户端请求数据但是不加载文件中的数据,并且一个客户端开一个kafka连接直接取数据处理后返回,内存稳定不会增加
4、客户端请求数据并且加载文件中的数据,但是,每一个客户端都会开启一个新的kafka连接直接取数据(相当于只是做了一个文件加载的动作,但是没有使用缓存里的数据)这样也会导致内存一直上升。

综合上面几种情况,我实在没想懂是为什么造成这种情况的了
代码图目前暂时没有拍,人在地铁上用手机发的帖子,其他地方都用控制变量法测试了很多次,目前唯一满足正常情况的就是不加载离线文件不走缓存直接连接kafka取数据。不知道各位看到这有没有啥思路