Исходники и презентации
This commit is contained in:
36
lessons/garbage_collector/add_cleanup/main.go
Normal file
36
lessons/garbage_collector/add_cleanup/main.go
Normal file
@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileWrapper struct {
|
||||
file *os.File
|
||||
}
|
||||
|
||||
func NewFileWrapper(path string) *FileWrapper {
|
||||
file, _ := os.OpenFile(path, os.O_RDONLY|os.O_CREATE, 0666)
|
||||
|
||||
ptr := &FileWrapper{file: file}
|
||||
|
||||
runtime.AddCleanup(ptr, func(f *os.File) { // replace with FileWrapper
|
||||
fmt.Println("Closing file:", f.Name())
|
||||
_ = f.Close()
|
||||
}, ptr.file)
|
||||
|
||||
return ptr
|
||||
}
|
||||
|
||||
func main() {
|
||||
obj := NewFileWrapper(os.DevNull)
|
||||
_ = obj
|
||||
obj = nil
|
||||
|
||||
runtime.GC()
|
||||
time.Sleep(time.Second)
|
||||
|
||||
fmt.Println("Object is collected by GC")
|
||||
}
|
||||
21
lessons/garbage_collector/big_allocations/main.go
Normal file
21
lessons/garbage_collector/big_allocations/main.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// GOGC=off go run main.go
|
||||
|
||||
var data []byte
|
||||
|
||||
func main() {
|
||||
count := 0
|
||||
|
||||
for {
|
||||
data = make([]byte, 1<<30)
|
||||
for idx := 0; idx < 1<<30; idx += 4096 {
|
||||
data[idx] = 100
|
||||
}
|
||||
|
||||
fmt.Println("allocated GB:", count)
|
||||
count++
|
||||
}
|
||||
}
|
||||
33
lessons/garbage_collector/finalizers/main.go
Normal file
33
lessons/garbage_collector/finalizers/main.go
Normal file
@ -0,0 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Data struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func NewData(name string) *Data {
|
||||
data := &Data{
|
||||
name: name,
|
||||
}
|
||||
|
||||
fmt.Println("created", name)
|
||||
runtime.SetFinalizer(data, func(ptr *Data) {
|
||||
fmt.Println("finalizer called on addr", unsafe.Pointer(ptr), "value is", ptr.name)
|
||||
})
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := NewData("__data__")
|
||||
_ = data
|
||||
|
||||
runtime.GC()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
19
lessons/garbage_collector/finalizers_any_times/main.go
Normal file
19
lessons/garbage_collector/finalizers_any_times/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
x := new(int)
|
||||
*x = 100
|
||||
|
||||
runtime.SetFinalizer(x, func(ptr *int) {
|
||||
fmt.Println("finalizer called on addr", ptr, "value is", *ptr)
|
||||
})
|
||||
|
||||
runtime.SetFinalizer(x, func(ptr *int) { // replace with nil
|
||||
fmt.Println("finalizer called on addr", ptr, "value is", *ptr)
|
||||
})
|
||||
}
|
||||
34
lessons/garbage_collector/finalizers_cycle/main.go
Normal file
34
lessons/garbage_collector/finalizers_cycle/main.go
Normal file
@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Foo struct {
|
||||
bar *Bar
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
foo *Foo
|
||||
}
|
||||
|
||||
func main() {
|
||||
foo := &Foo{}
|
||||
bar := &Bar{}
|
||||
|
||||
foo.bar = bar
|
||||
bar.foo = foo
|
||||
|
||||
runtime.SetFinalizer(foo, func(ptr *Foo) {
|
||||
fmt.Println("finalizer called on addr", ptr, "value is", *ptr)
|
||||
})
|
||||
|
||||
runtime.SetFinalizer(bar, func(ptr *Bar) {
|
||||
fmt.Println("finalizer called on addr", ptr, "value is", *ptr)
|
||||
})
|
||||
|
||||
runtime.GC()
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
22
lessons/garbage_collector/finalizers_not_first_word/main.go
Normal file
22
lessons/garbage_collector/finalizers_not_first_word/main.go
Normal file
@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Foo struct {
|
||||
a int
|
||||
b string
|
||||
}
|
||||
|
||||
func main() {
|
||||
foo := &Foo{a: 1, b: "hello"}
|
||||
runtime.SetFinalizer(&foo.b, func(ptr *string) {
|
||||
fmt.Println("finalizer called on addr", ptr, "value is", *ptr)
|
||||
})
|
||||
|
||||
runtime.GC()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
38
lessons/garbage_collector/finalizers_resurrection/main.go
Normal file
38
lessons/garbage_collector/finalizers_resurrection/main.go
Normal file
@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var globalData *Data
|
||||
|
||||
type Data struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func NewData(name string) *Data {
|
||||
data := &Data{
|
||||
name: name,
|
||||
}
|
||||
|
||||
fmt.Println("created", name)
|
||||
runtime.SetFinalizer(data, func(ptr *Data) {
|
||||
fmt.Println("finalizer called on addr", unsafe.Pointer(ptr), "value is", ptr.name)
|
||||
globalData = ptr
|
||||
})
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := NewData("data")
|
||||
_ = data
|
||||
|
||||
runtime.GC()
|
||||
time.Sleep(time.Second)
|
||||
|
||||
fmt.Println("resurrected on addr", unsafe.Pointer(globalData), "value is", globalData.name)
|
||||
}
|
||||
15
lessons/garbage_collector/finalizers_unsafe_type/main.go
Normal file
15
lessons/garbage_collector/finalizers_unsafe_type/main.go
Normal file
@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
x := new(int)
|
||||
*x = 100
|
||||
|
||||
runtime.SetFinalizer(x, func(ptr *float64) {
|
||||
fmt.Println("finalizer called on addr", ptr, "value is", *ptr)
|
||||
})
|
||||
}
|
||||
8
lessons/garbage_collector/memory_ballast/main.go
Normal file
8
lessons/garbage_collector/memory_ballast/main.go
Normal file
@ -0,0 +1,8 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
ballast := make([]byte, 2<<30)
|
||||
_ = ballast
|
||||
|
||||
// implementation ...
|
||||
}
|
||||
48
lessons/garbage_collector/weak_map/main.go
Normal file
48
lessons/garbage_collector/weak_map/main.go
Normal file
@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"time"
|
||||
"weak"
|
||||
)
|
||||
|
||||
type WeakMap struct {
|
||||
data map[string]weak.Pointer[string]
|
||||
}
|
||||
|
||||
func NewWeakMap() WeakMap {
|
||||
return WeakMap{
|
||||
data: make(map[string]weak.Pointer[string]),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WeakMap) Set(key string, value *string) {
|
||||
runtime.AddCleanup(value, w.Delete, key)
|
||||
w.data[key] = weak.Make(value)
|
||||
}
|
||||
|
||||
func (w *WeakMap) Get(key string) *string {
|
||||
if ptr, ok := w.data[key]; ok {
|
||||
return ptr.Value()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *WeakMap) Delete(key string) {
|
||||
delete(w.data, key)
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := NewWeakMap()
|
||||
|
||||
key := "my key"
|
||||
value := "my data"
|
||||
data.Set(key, &value)
|
||||
|
||||
runtime.GC()
|
||||
time.Sleep(time.Second)
|
||||
|
||||
pointer := data.Get(key)
|
||||
println(pointer == nil)
|
||||
}
|
||||
18
lessons/garbage_collector/weak_ptr/main.go
Normal file
18
lessons/garbage_collector/weak_ptr/main.go
Normal file
@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
"weak"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pointer := new(string)
|
||||
weakPtr := weak.Make(pointer)
|
||||
|
||||
runtime.GC()
|
||||
time.Sleep(time.Second)
|
||||
|
||||
fmt.Println(weakPtr.Value() == nil)
|
||||
}
|
||||
Reference in New Issue
Block a user