我可以取消分配Golang中slice元素占用的空间吗?

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

我正在尝试使用Slice实现队列。但是切片的问题在于,切片后,修剪后的元素会继续占据空间。因此,我想知道是否仍然可以删除占用的空间,或者换句话说,不分配所修剪元素的空间。

queue := make([]int, 0)
//Enqueue
queue = append(queue, 1)
queue = append(queue, 2)
queue = append(queue, 3)
//Dequeue
deletedElement := queue[0]
//--unallocate the space occupied by queue[0]
queue = queue[1:]
go slice
1个回答
0
投票

queue是一个切片,它指向一个后备数组。切片覆盖(或在切片时覆盖的)块有多大比例都没有关系,只要存在对数组的引用,它将被保存在内存中。当没有更多引用时,垃圾收集器将释放它。

[当您使用queue将新元素添加到append()时,如果后备数组无法容纳其他元素,它将自动分配一个新数组,将现有元素复制到该数组,然后旧数组将不会被queue引用。如果没有其他引用,它将被释放。

如果您不想等待发生这种情况,则唯一的选择是创建一个新的数组或切片,将队列元素复制到其中,然后更新queue slice标题以指向此新切片(这样可以释放旧的)。

例如:

//Dequeue
deletedElement := queue[0]
//--unallocate the space occupied by queue[0]
queue = queue[1:]

newQueue := make([]int, len(queue))
copy(newQueue, queue)
queue = newQueue

您可以稍微简化一下:

queue = append(make([]int, 0, len(queue)), queue...)

如您所见,这只是释放一个int的空间的开销很大的操作。因此,仅在未使用的空间很大时,才应在每次出队后执行此操作。

还请注意,在创建新切片时,您可以使用更大的容量,因此可以在不引起立即重新分配的情况下将新元素放入队列,例如:

queue = append(make([]int, 0, 2* len(queue)), queue...)
© www.soinside.com 2019 - 2024. All rights reserved.