变量超出循环、条件或案例的范围后会发生什么?

问题描述 投票:0回答:2

这个问题的原因只是我的好奇心,想确定编写从多个通道读取大型字节数组的高性能流消费者的最佳实践是什么。 (虽然过早的优化是万恶之源,但这更多是出于好奇)。我已经阅读了有关

C
here 的类似 senario 的答案,但我要求具体的答案,因为它是一种垃圾收集语言,他们的文档 here 说“从正确性的角度来看,你不需要知道变量的分配位置。

如果我有以下代码从频道读取,

    for {
    select {
    case msg := <-stream.Messages():
    ...snip...

变量

msg
在案例陈述的范围内。

  • 一旦超出
    case
    声明的范围会发生什么?由于这是在同一个本机函数中声明的,并且
    stream
    的大小可能是一个大字节切片,因此变量将存储在堆或堆栈中,如果是堆,它将被垃圾收集,还是堆栈指针进入画面?
  • 因为这是在一个无限循环中,而且
    stream
    的大小是一个大字节切片,每次创建变量和分配内存都是一个开销,或者我应该提前声明变量,并继续覆盖它在每次迭代中,如果涉及垃圾收集,我不确定,我可能会减少垃圾?
  • 我根本不应该为此烦恼吗?
go memory-management garbage-collection heap-memory stack-memory
2个回答
4
投票

我根本不应该为此烦恼吗?

(一旦它困扰你:个人资料。)


3
投票

如果通道值类型是切片,变量

msg
的值只是切片描述符,很小(见https://blog.golang.org/go-slices-usage-and-internals ).包含切片引用的数据的数组将在切片放置在通道上之前分配到别处。假设该值必须在分配它的函数返回后存活,它将在堆上。请注意,切片的内容实际上并没有被通道接收操作移动或复制。

一旦

msg
的值变得不可访问(通过变量超出范围或被分配不同的值),假设没有其他对切片底层数组的引用,它将受到垃圾收集。

如果不了解程序的工作原理,很难说一定程度的优化是否有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.