当使用`unsafe`将`[]byte`转换为字符串时,`capacity`内存会发生什么变化?

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

What happens to the 'capacity' memory when using unsafe to convert a []byte to a string?

问题

我看到人们使用unsafe.Pointer来高效地将[]byte转换为string。https://play.golang.org/p/uz84H54VM8

var b = []byte{'f', 'o', 'o', 'b', 'a', 'r'}
var s = *(*string)(unsafe.Pointer(&b))

我理解它的作用以及一般情况下涉及的危险,但对于内存有一个问题。

由于切片的结构包含数据指针、长度和容量,但字符串没有容量,如果b是在堆上创建的,那么这段内存会发生什么情况?垃圾回收器是否知道它需要单独跟踪容量?或者这可能导致内存泄漏吗?

编辑:

我知道如何对字符串和切片进行重新切片。上面的代码是用于在需要从[]byte转换为string但又想避免完全复制时使用的。

问题是我们从结构中删除了capacity,这是否会导致垃圾回收问题。

英文:

I have seen people use unsafe.Pointer to efficiently convert a []byte to a string. https://play.golang.org/p/uz84H54VM8

var b = []byte{'f', 'o', 'o', 'b', 'a', 'r'}
var s = *(*string)(unsafe.Pointer(&b))

I understand what it is doing as well as the dangers involved in general but have a question about the memory.

Since the structure of a slice has a data pointer, a length, and a capacity, but the string doesn't have the capacity, what happens to that memory if b was created on the heap? Does the garbage collector know that it needs to track the capacity separately? Or could this cause a memory leak?

EDIT:

I understand how to reslice strings and slices. The above code is for when you need to convert from []byte to string but want to avoid a full copy.

The question is about the capacity that we're dropping from the structure and if it causes GC problems.

答案1

得分: 3

语句var s = *(*string)(unsafe.Pointer(&b))将数据和长度从切片头部值(SliceHeader)复制到字符串头部值(StringHeader)。

该语句不会改变运行时对切片头部的解释。切片头部的容量不会被丢弃。

仅仅复制数据和长度不会引起垃圾回收问题。

  • 复制操作后,字符串头部和切片头部的值仍然有效。
  • 垃圾回收器不会假设字符串的底层数组大小等于字符串头部的长度。例如,垃圾回收器会处理安全的代码s := "foobarxxx"[:6],其中字符串头部s的长度为6,而底层数组的大小为9。
英文:

The statement var s = *(*string)(unsafe.Pointer(&b)) copies the data and length from a slice header value to a string header value.

The statement does not change the runtime's interpretation of the slice header. The capacity is not dropped from the slice header.

Copying the data and length only does not cause GC problems.

  • The string header and slice header values are both valid after the copy operation.
  • The garbage collector does not assume that the size of a string backing array is equal to the length in the string header. For example, the GC handles the safe code s := "foobarxxx"[:6] where the string header s has length 6 and the backing array has size 9.

huangapple
  • 本文由 发表于 2017年2月14日 00:43:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/42209149.html
匿名

发表评论

匿名网友

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

确定