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?
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.
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.
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.
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.
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.
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:
If obj
is a zero size type, the value of the expression may not be unique, as described in the spec.
Over the lifetime of a program, a particular uintptr
value might refer to different objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With