runtime.AddCleanup
Помните наш блоб?
b := newBlob(1000)
fmt.Printf("b=%v, type=%T\n", b, b)
b=Blob(1000 KB), type=*main.Blob
Что если мы хотим запустить некоторую функцию очистки (cleanup function), когда объект будет собран сборщиком мусора?
Раньше для этого мы бы вызывали runtime.SetFinalizer
, который сложно использовать. Теперь есть его улучшенная версия — runtime.AddCleanup
:
func main() {
b := newBlob(1000)
now := time.Now()
// Регистрируем функцию, которую рантайм
// вызовет после сборки памяти объекта b.
runtime.AddCleanup(b, cleanup, now)
time.Sleep(10 * time.Millisecond)
b = nil
runtime.GC()
time.Sleep(10 * time.Millisecond)
}
func cleanup(created time.Time) {
fmt.Printf(
"object is cleaned up! lifetime = %dms\n",
time.Since(created)/time.Millisecond,
)
}
object is cleaned up! lifetime = 10ms
AddCleanup
прикрепляет функцию очистки к объекту. Она выполняется после того как объект становится недоступен (на него больше никто не ссылается).
Функция очистки выполняется в отдельной горутине — она последовательно обрабатывает все вызовы очистки в рамках программы. К одному и тому же указателю можно прикрепить несколько функций очистки.
Обратите внимание, что функция очистки не обязательно выполняется сразу после того, как объект стал недоступен; она может выполниться в любое время в будущем.
Более полный пример, который демонстрирует совместную работу слабых указателей и AddCleanup
— в песочнице.
★ Подписывайтесь на новые заметки.