the*_*tem 4 string garbage-collection go slice
根据这篇Go Data Structures文章,在Strings部分下,它指出采用一个字符串片段会将原始字符串保留在内存中.
"(另外,在Java和其他语言中有一个众所周知的问题,当你切割一个字符串来保存一小块时,对原始文件的引用会将整个原始字符串保留在内存中,即使只有少量仍然存在Go也有这个问题.我们尝试和拒绝的替代方案是使字符串切片如此昂贵 - 分配和副本 - 大多数程序都避免使用它.)"
所以如果我们有一个很长的字符串:
s := "Some very long string..."
Run Code Online (Sandbox Code Playgroud)
我们采取一小部分:
newS := s[5:9]
Run Code Online (Sandbox Code Playgroud)
在s我们发布之前,原件不会发布newS.考虑到这一点,如果我们需要newS长期保留,但是s为垃圾收集发布,采取什么方法?
我想也许这个:
newS := string([]byte(s[5:9]))
Run Code Online (Sandbox Code Playgroud)
但我不确定这是否真的有用,或者是否有更好的方法.
是的,转换为一个字节片段将创建字符串的副本,因此原始字符串不再被引用,并且可以在某个地方进行GC.
作为这个的"证明"(好吧,它证明了字节切片不与原始字符串共享相同的底层数据):
http://play.golang.org/p/pwGrlETibj
编辑:并证明字节片只有必要的长度和容量(换句话说,它的容量不等于原始字符串的容量):
http://play.golang.org/p/3pwZtCgtWv
Edit2:你可以清楚地看到内存分析会发生什么.在reuseString()中,使用的内存非常稳定.在copyString()中,它快速增长,显示由[]字节转换完成的字符串副本.
http://play.golang.org/p/kDRjePCkXq