1// run 2 3// Copyright 2018 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7package main 8 9import ( 10 "fmt" 11 "runtime" 12) 13 14type HeapObj [8]int64 15 16type StkObj struct { 17 h *HeapObj 18} 19 20var n int 21var c int = -1 22 23func gc() { 24 // encourage heap object to be collected, and have its finalizer run. 25 runtime.GC() 26 runtime.GC() 27 runtime.GC() 28 n++ 29} 30 31func main() { 32 f() 33 gc() // prior to stack objects, heap object is not collected until here 34 if c < 0 { 35 panic("heap object never collected") 36 } 37 if c != 1 { 38 panic(fmt.Sprintf("expected collection at phase 1, got phase %d", c)) 39 } 40} 41 42func f() { 43 var s StkObj 44 s.h = new(HeapObj) 45 runtime.SetFinalizer(s.h, func(h *HeapObj) { 46 // Remember at what phase the heap object was collected. 47 c = n 48 }) 49 g(&s) 50 gc() 51} 52 53func g(s *StkObj) { 54 gc() // heap object is still live here 55 runtime.KeepAlive(s) 56 gc() // heap object should be collected here 57} 58