英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论