小编典典

切片后释放字符串以进行垃圾回收的正确方法

go

根据此Go Data Structures文章的介绍,在“ 字符串”
部分下,它声明获取字符串的一部分会将原始字符串保留在内存中。

“(顺便说一句,在Java和其他语言中,有一个众所周知的陷阱,当您对字符串进行切片以保存一小段时,对原始字符串的引用会将整个原始字符串保留在内存中,即使仍然很少Go也有这个陷阱。我们尝试并拒绝的替代方法是使字符串切片变得如此昂贵(分配和复制),以至于大多数程序都避免了。)”

因此,如果我们有一个很长的字符串:

s := "Some very long string..."

我们采取一小部分:

newS := s[5:9]

s我们也发布之前,不会发布原始文件newS。考虑到这一点,如果我们需要保持newS长期状态,但s为了垃圾回收而释放,该采取什么适当的方法呢?

我想也许是这样的:

newS := string([]byte(s[5:9]))

但是我不确定这是否会切实可行,或者是否有更好的方法。


阅读 303

收藏
2020-07-02

共1个答案

小编典典

是的,转换为字节的一部分将创建该字符串的副本,因此不再引用原始的字符串,并且可以在行下的某处进​​行GC处理。

作为对此的“证明”(很好,它证明了字节片与原始字符串不共享相同的基础数据):

http://play.golang.org/p/pwGrlETibj

编辑:并证明字节片仅具有必要的长度和容量(换句话说,其容量不等于原始字符串的容量):

http://play.golang.org/p/3pwZtCgtWv

Edit2:您可以清楚地看到内存配置文件发生了什么。在reuseString()中,使用的内存非常稳定。在copyString()中,它增长很快,显示了[]
byte转换完成的字符串的副本。

http://play.golang.org/p/kDRjePCkXq

2020-07-02