为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
RISEBY 2021-05-14 15:04:02
根据此Go Data Structures文章的介绍,在“字符串”部分下,它声明对字符串进行切片将使原始字符串保留在内存中。“(顺便说一句,Java 和其他语言中有一个众所周知的问题,当您将字符串切片以保存一小部分时,对原始字符串的引用会将整个原始字符串保留在内存中,即使只有一小部分仍然存在Go也有这个陷阱。我们尝试并拒绝的替代方法是使字符串切片变得如此昂贵(分配和复制),以至于大多数程序都避免了。)”因此,如果我们有一个很长的字符串:s := "Some very long string..."我们采取一小部分:newS := s[5:9]在s我们也发布之前,不会发布原始文件newS。考虑到这一点,如果我们需要保持newS长期状态,但s为了垃圾收集而释放,该采取什么适当的方法呢?我想也许是这样的:newS := string([]byte(s[5:9]))但是我不确定这是否会切实可行,或者是否有更好的方法。
查看完整描述

2 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

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

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

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

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

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

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

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


查看完整回答
反对 回复 2021-05-31
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

确保对字符串进行切片并使其保持“活动”状态后,最终可能有资格进行垃圾回收的正确方法是创建该切片的副本,然后使该副本“保持活动”。但是现在人们正在以牺牲更糟糕的时间性能为代价来购买更好的内存性能。可能在某个地方是好的,但在其他地方可能是邪恶的。有时,只有正确的测量而不是猜测,才能告诉您真正的增益在哪里。

查看完整回答
反对 回复 2021-05-31
  • 2 回答
  • 0 关注
  • 249 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信