Rya*_*ach 5 garbage-collection go
我正在和一个朋友争论,讨论Go中可能浪费的资源。
如果Reader在内存中的字节数组上运行,是否必须将其关闭?
func readJar(zipBytes []byte, readMeta bool) (m jar.Manifest, err error) {
reader, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
if err != nil {
return
}
for _, file := range reader.File {
switch file.Name {
case jar.ManifestPath:
m, err = readManifest(file)
if err != nil {
return
}
}
}
return
}
func readManifest(file *zip.File) (jar.Manifest, error) {
reader, err := file.Open()
if err != nil {
return nil, err
}
defer reader.Close()
return jar.ReadManifest(reader)
}
Run Code Online (Sandbox Code Playgroud)
最初它被认为是文件句柄泄漏的来源,但其他原因也应归咎于此。
这个泄漏内存还是Go可以进行足够的转义分析/垃圾收集?
Golang 编译器会处理无法访问的变量:-
存储位置确实对编写高效程序有影响。如果可能,Go 编译器将在该函数的堆栈帧中分配该函数的本地变量。但是,如果编译器无法证明函数返回后该变量未被引用,则编译器必须在垃圾收集堆上分配该变量以避免悬空指针错误。此外,如果局部变量非常大,将其存储在堆上而不是堆栈上可能更有意义。
虽然Golang包含垃圾收集。最好使用清理功能。您可以使用 defer 函数在函数结束时关闭文件。
defer f.close()
Run Code Online (Sandbox Code Playgroud)
查看SetFinalizer的文档以更好地了解这些概念:
func SetFinalizer(obj interface{}, finalizer interface{})
Run Code Online (Sandbox Code Playgroud)
SetFinalizer 将与 obj 关联的终结器设置为提供的终结器函数。当垃圾收集器发现具有关联终结器的不可访问块时,它会清除关联并在单独的 goroutine 中运行 Finalizer(obj)。这使得 obj 再次可访问,但现在没有关联的终结器。假设SetFinalizer不再被调用,下次垃圾收集器发现obj不可访问时,就会释放obj。
终结器为对象运行以检查它是否无法从源访问。它可用于文件描述符,但依赖终结器来刷新内存中的 I/O 缓冲区(例如 bufio.Writer)是错误的,因为缓冲区在程序退出时不会被刷新。