go版本开发+644ddaa842 星期三,11月7日,16:12:02,2018 +0000 linux/amd64
新创建的类型不会被垃圾回收,因此根据运行时数据实时创建类型的代码可能会泄漏内存。
这段代码在应该输出零的时候输出了一个很大的数字:https://play.golang.org/p/R6N6IJSzYTD
go版本开发+644ddaa842 星期三,11月7日,16:12:02,2018 +0000 linux/amd64
新创建的类型不会被垃圾回收,因此根据运行时数据实时创建类型的代码可能会泄漏内存。
这段代码在应该输出零的时候输出了一个很大的数字:https://play.golang.org/p/R6N6IJSzYTD
5条答案
按热度按时间cnjp1d6j1#
是的。这是一个很难修复的问题。
我们依赖于类型唯一性,所以我们需要跟踪我们目前创建的所有类型。
要对类型进行垃圾回收,我们需要一种方法告诉
reflect
我们已经完成了这个操作,这样它就可以从其创建类型的列表中删除该类型。可能类似于Java的弱引用。所有接口表都分配在持久性内存中,而不是堆上,因此这也需要改变。
编译器对类型和接口表永远不会被垃圾回收有一些假设(例如,接口的第一个字节不是一个GC需要遍历的指针),这也需要找到并修复。
与 #20461 有一些相关性。
ovfsdjhp2#
你能否将运行时类型分为两部分:一个持久分配的单字节间接指针,指向第二个可进行垃圾回收的部分及其所有字段?但这只是一种常数因子的改进,而且可能会延迟问题。
tzdcorbm3#
我刚刚发现,我开发的API框架在使用反射时会泄漏内存。也许在reflect包上应该有一个关于类型不会被垃圾回收的说明?
p1iqtdky4#
我也认为这只需要更好地记录,不需要修复。reflect包是一个Maven接口,因此它的用户需要采取预防措施,而不是Go团队。
指针类型和堆外类型信息对我来说至少比使用Maven级API的奇怪用法更方便和安全更有价值。
6tdlim6h5#
通过指针和堆外类型信息进行类型标识
这对我来说听起来像是在逃避问题。我不相信允许类型被垃圾回收(GC)必然意味着这两件事情都不能做。
虽然这可能现在看起来是一个小问题,但如果我们解决了Go的插件系统,我认为它会变得更加重要。
此外,在reflect包中没有任何内容表明“不要创建无限数量的新类型,因为你会导致内存泄漏”。也许应该有,但我更希望这个问题实际上能够得到解决,即使需要一段时间。