best way to remove element from slice

huangapple go评论80阅读模式
英文:

best way to remove element from slice

问题

我正在尝试从切片中删除一个元素,并且想知道这种方式是否会导致应用程序中的内存泄漏。

func RemoveElementInSlice(list []int32, idx int) []int32 {
	list[idx] = list[len(list)-1]
	list = list[:len(list)-1]
	return list
}

这里的list是我想要从中删除索引为idx的元素的切片。
如果这可能会导致内存泄漏,那么最好且安全的方法是什么?

英文:

I am trying to remove an element from a slice and I am wondering if this way will cause any memory leak in the application.

func RemoveElementInSlice(list []int32, idx int) []int32 {
	list[idx] = list[len(list)-1]
	list = list[:len(list)-1]
	return list
}

Here list is the slice from which I want to remove the element at index idx.
If this might cause a memory leak what is the best & safe way to do it?

答案1

得分: 2

如《Kind-of Memory Leaking Caused by Subslices》中所解释的:

类似于子字符串,子切片也可能导致某种形式的内存泄漏。

在下面的代码中,在调用g函数之后,如果没有其他值引用内存块中托管s1元素的大部分内存将会丢失。

var s0 []int

func g(s1 []int) {
	// 假设s1的长度远大于30。
	s0 = s1[len(s1)-30:]
}

如果我们想避免这种内存泄漏,我们必须为s0复制这30个元素,这样s0的存活将不会阻止托管s1元素的内存块被回收。

func g(s1 []int) {
	s0 = make([]int, 30)
	copy(s0, s1[len(s1)-30:])
	// 现在,如果没有其他值引用该内存块,那么托管s1元素的内存块可以被回收。
}

但是你可以使用pprof进行调查,如《Golang slice memory leak collection》中所示:

// 在导入中添加pprof包
_ "net/http/pprof"

然后:

go tool pprof http://127.0.0.1:9999/debug/pprof/heap

另请参阅icza的答案。

英文:

As explained in "Kind-of Memory Leaking Caused by Subslices":

> Similarly to substrings, subslices may also cause kind-of memory leaking.
>
> In the following code, after the g function is called, most memory occupied by the memory block hosting the elements of s1 will be lost (if no more values reference the memory block).
>
>go
>var s0 []int
>
>func g(s1 []int) {
> // Assume the length of s1 is much larger than 30.
> s0 = s1[len(s1)-30:]
>}
>

>
>If we want to avoid the kind-of memory leaking, we must duplicate the 30 elements for s0, so that the aliveness of s0 will not prevent the memory block hosting the elements of s1 from being collected.
>
>```go
>func g(s1 []int) {
> s0 = make([]int, 30)
> copy(s0, s1[len(s1)-30:])
> // Now, the memory block hosting the elements
> // of s1 can be collected if no other values
> // are referencing the memory block.
>}


---

But you can investigate that with pprof, as illustrated in "[Golang slice memory leak collection][2]"

```go
//Add pprof package in import
_ "net/http/pprof"

Then:

go tool pprof http://127.0.0.1:9999/debug/pprof/heap

See also icza's answer.

huangapple
  • 本文由 发表于 2021年5月21日 14:47:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/67632026.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定