Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Go guarantee constant addresses?

Given an object obj is there a guarantee that

uintptr(unsafe.Pointer(&obj))

will always evaluate to the same value regardless of when it is called?

Of course, Go guarantees that if you take two pointers to the same object, they will always compare equal. It might be possible though that an implementation moves an object in memory and transparently updates all pointers to it.

This is interesting if you consider garbage collection strategies like Mark-and-Compact. Would an implementor be allowed to use such a garbage collection strategy?

like image 253
fuz Avatar asked Mar 05 '14 11:03

fuz


People also ask

Does Go GC stop the world?

The Go GC, however, is not fully stop-the-world and does most of its work concurrently with the application. This is primarily to reduce application latencies.

How does the garbage collector work in Go?

Garbage collection is a mechanism Go developers use to find memory space that is allocated recently but is no longer needed, hence the need to deallocate them to create a clean slate so that further allocation can be done on the same space or so that memory can be reused.

How often does Go GC run?

It's a heuristic. The Go developers probably observed that starting a GC approximately every two minutes was a reasonable trade-off between the overhead of a GC cycle and memory used.

Is Golang garbage collected?

Go is a garbage collected language. This makes writing Go simpler, because you can spend less time worrying about managing the lifetime of allocated objects. Memory management is definitely easier in Go than it is in, say, C++. But it's also not an area we as Go developers can totally ignore, either.


2 Answers

There is no such guarantee, exactly so that it is possible to implement a moving collector.

In fact, although the garbage collector does not move heap objects today, in Go 1.3 stacks can move when needing to grow, so it is entirely possible that

var obj int
fmt.Println(uintptr(unsafe.Pointer(&obj)))
bigFunc()
fmt.Println(uintptr(unsafe.Pointer(&obj)))

will print two different pointers, because bigFunc grew the stack, causing obj and everything else on the stack to move.

like image 63
Russ Cox Avatar answered Oct 13 '22 18:10

Russ Cox


There isn't anything in the specification that guarantees this, probably to allow implementations of the language to use compacting garbage collectors in the future. In this golang-nuts thread one of the developers suggests that a compacting GC would be possible provided unsafe.Pointer values were pinned in memory, but this couldn't extend to all unitptr values.

For the current Go runtime I believe it is true, but relying on it would still be undefined behaviour. There are a few caveats though:

  1. If obj is a zero size type, the value of the expression may not be unique, as described in the spec.

  2. Over the lifetime of a program, a particular uintptr value might refer to different objects.

like image 39
James Henstridge Avatar answered Oct 13 '22 19:10

James Henstridge