go - 我使用 pprof 进行的 golang 程序分析显示内存在 std/json 包中的 json (* decodeState) objectInterface 处增加
问题描述
我有一个使用 std“encoding/json”包中的 unmarshall 的 golang 程序,它的大小不断增加(内存泄漏)。使用 pprof 的内存配置图显示 json (* decodeState) objectInterface 处的内存增加。我想了解解决问题的方式和原因。
我在上层尝试了几件事,比如释放返回值以避免泄漏,但没有成功。
func (j JSONEncoding) From(b []byte, msg interface{}) (interface{}, error) {
err := json.Unmarshal(b, &msg)
return msg, err
}
pprof top5 显示了这个调用,以及下面的详细信息;
4096.89kB 24.43% 24.43% 4096.89kB 24.43% encoding/json.(*decodeState).objectInterface
(pprof) list objectInterface
Total: 20.65MB
ROUTINE ======================== encoding/json.(*decodeState).objectInterface in /usr/local/go/src/encoding/json/decode.go
6MB 7.50MB (flat, cum) 36.32% of Total
. . 1061: return v
. . 1062:}
. . 1063:
. . 1064:// objectInterface is like object but returns map[string]interface{}.
. . 1065:func (d *decodeState) objectInterface() map[string]interface{} {
3MB 3MB 1066: m := make(map[string]interface{})
. . 1067: for {
. . 1068: // Read opening " of string key or closing }.
.
. deleted code
.
. . 1095:
. . 1096: // Read value.
3MB 4.50MB 1097: m[key] = d.valueInterface()
使用topN,并使用可视化,我可以看到这个框随着时间/处理而增加。
这个 unmarshall 在循环中被调用,但没有保存任何可能是泄漏的原因。我不确定如何以及如何做一些事情来避免这种泄漏。
更新:内存泄漏更多的是内存累积,在其他地方的代码中。在尝试编写显示问题的最小代码时,我无法重现,并且不得不挖掘所有代码以发现内部库正在使用映射来缓存并且缓存清理器无法正常工作。
我的问题是 pprof 正在提供有关谁在分配的信息,而不是它的保存位置。我想我的问题应该是,我们怎样才能找出哪些对象有什么大小的引用。我知道一个分配的参考可能在多个地方,但这些信息很容易帮助找到这类问题。
解决方案
问:你为什么不做这样的事情:
https://golang.org/pkg/encoding/json/
func (a *Animal) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
switch strings.ToLower(s) {
default:
*a = Unknown
case "gopher":
*a = Gopher
case "zebra":
*a = Zebra
}
return nil
}
换句话说,您的实现是否防止对象(例如“err”)被垃圾收集?
推荐阅读
- java - java 1.7 中的标志参数无效
- laravel - Laravel Cashier (Stripe) 使用带有令牌的现有客户订阅
- docker - Nginx 反向代理到 HTTPS 上游得到 502 Bad Gateway?
- scikit-learn - 为什么 SVC、NuSVC 和 LinearSVC 会产生截然不同的结果?
- unix - 如何使用 egrep 查找重复的字符簇(例如 abc-abc-abc)?
- mysql - 如何将存储在 MySQL 单元中的代码输入我的 Python beautifulsoup
- autohotkey - “#SingleInstance force”被忽略
- indexing - Solr managed-schema '为了获得最佳索引大小和搜索性能,将“index”设置为 false'。为什么?
- java - 如何从不可变链表中删除?
- asp.net-mvc - 在 Razor 视图中使用根 url 创建链接