Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

golang中用Json Decoder产生的大量内存消耗问题 #139

Open
AlexiaChen opened this issue May 10, 2021 · 5 comments
Open

golang中用Json Decoder产生的大量内存消耗问题 #139

AlexiaChen opened this issue May 10, 2021 · 5 comments
Labels
golang go programming language 软件调试 调试技巧,思考

Comments

@AlexiaChen
Copy link
Owner

AlexiaChen commented May 10, 2021

因为项目中的RPC接口经过大量调用,通过pprof看到的结果就是消耗在了reflect.,mapassign 等由json decoder引起的问题。

unknown

上图就是我本地复现的情况

经过google,发现/thanos也有这个issue,经过他们讨论被一个临时的PR缓解了,他们的svg调用图为以下,看起来跟我们的pprof结果很一致。

最终的临时方案就是用json.Unmarshal 替换NewDecoder().decode。 这样会好一些,但是也只是缓解该现象。没有彻底解决,所以当时他们这个issue 还是打开的。

也许reflect相关的GC问题比较难修复,go官方的issue也提到了,但是还没有close golang/go#28783 静观其变吧。要不就是直接把json这个换成其他的格式,但是这与我们项目的的目的背道而驰,因为几乎所有区块链都支持json RPC。

最后还是发现一个中文社区的朋友也遇到我类似的问题: http://javagoo.com/go/mapassign.html, 他的解决方案是:

既然decodeMap消耗内存严重,我们就放弃使用map。Transfer rpc之前,先将map转成string,然后Judge再将string转成map。

所以他是设法绕过一些问题。我看也有一些项目是用protobuf等格式取代json的,但是我们的项目行不通,json无法取代。

当然这个问题如果有大量RPC访问,是会触发OOM的,json.decode还有RLP.decode都会消耗大量内存,以太坊就有很类似的两个issues(因为从pprof的结果上上看很一致),最终经过一番调查都没有内存泄露,给出的建议是加入rate limiter:

当然,还有一个就是尽量把json的缓存,还有其他缓存加上。

@AlexiaChen AlexiaChen added 软件调试 调试技巧,思考 golang go programming language labels May 10, 2021
@songtianyi
Copy link

ethereum 怎么处理的

@AlexiaChen
Copy link
Owner Author

ethereum 怎么处理的

估计是外部有限流器,LoadBalancer什么的。因为我们就是用了以太坊的壳子,可以把RPC注册到ETH的框架里面。

@DemoLiang
Copy link

所以这种jsonpb 编码导致大量内存开销,最后导致泄露的问题怎么解决

@AlexiaChen
Copy link
Owner Author

所以这种jsonpb 编码导致大量内存开销,最后导致泄露的问题怎么解决

没法解决。绕过去。或者换一个json库。

@DemoLiang
Copy link

所以这种jsonpb 编码导致大量内存开销,最后导致泄露的问题怎么解决

没法解决。绕过去。或者换一个json库。

有推荐的库吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
golang go programming language 软件调试 调试技巧,思考
Projects
None yet
Development

No branches or pull requests

3 participants