Skip to content

function StringToBytesWithNoCopy(s string) in pkg/util/util.go have some problems in GC scenarios #1432

@colin-si

Description

@colin-si

Describe the bug
The return result of the StringToBytesWithNoCopy function will be recycled by GC when a large number of objects are created.

To Reproduce
The following demo can reproduce this problem

var ResultKey []byte

func main() {
	key:=[]byte("123456789")
	ResultKey = StringToBytesWithNoCopy(string(key))
	// Result is normal before gc
	log.Printf("before runtime.gc and makeEscape: %v\n", string(ResultKey))
	runtime.GC()
	for i:=1;i<5000;i++{
		makeEscape(time.Now().String())
	}
	// Result has been recycled after gc
	log.Printf("after runtime.gc and makeEscape: %v\n",string(ResultKey))
}

func makeEscape(input string)string  {
	return  input
}

// method copy from servicecomb-service-center/pkg/util/util.go
func StringToBytesWithNoCopy(s string) []byte {
	x := (*[2]uintptr)(unsafe.Pointer(&s))
	h := [3]uintptr{x[0], x[1], x[1]}
	return *(*[]byte)(unsafe.Pointer(&h))
}

// use this method can solve the problem
func StringToBytesWithNoCopyNew(str string) []byte {
	return *(*[]byte)(unsafe.Pointer(
		&struct {
			string
			Cap int
		}{str, len(str)},
	))
}

Expected behavior
When we executed the above demo, we found that the returned results were recycled after GC. This was unexpected. The memory where ResultKey is located is recycled and reallocated for use elsewhere.

2023/12/13 10:57:20 before runtime.gc and makeEscape: 123456789
2023/12/13 10:57:20 after runtime.gc and makeEscape:  m=+0.017

Platform And Runtime (please complete the following information):

Platform

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Runtime

  • Version [e.g. Go 1.11]

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions