我正在和朋友吵架,讨论Go中可能浪费的资源。
如果Reader在内存中的字节数组上运行,是否必须关闭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)
}
最初它被认为是文件句柄泄漏的来源,但其他原因也应归咎于此。
此泄漏内存还是Go可以进行足够的转义分析/垃圾回收?
答案 0 :(得分:2)
Golang编译器负责unreachable variables:-
存储位置确实会影响写入效率 程式。如果可能,Go编译器将分配变量 对于该函数的堆栈框架中的某个函数而言是本地的。但是,如果 编译器无法证明之后没有引用该变量 函数返回,则编译器必须在 垃圾回收堆,以避免悬空的指针错误。另外,如果 局部变量很大,将其存储可能更有意义 在堆而不是堆栈上。
尽管Golang包含垃圾回收。最好使用清理功能。您可以使用defer函数在函数末尾关闭文件。
defer f.close()
查看SetFinalizer的文档以对这些概念有更多的了解:
func SetFinalizer(obj interface{}, finalizer interface{})
SetFinalizer将与obj关联的终结器设置为所提供的 终结函数。当垃圾收集器发现无法访问时 用关联的终结器阻止,清除关联并运行 finalizer(obj)在单独的goroutine中。这使得obj可达 再次,但是现在没有关联的终结器。假如说 下次没有垃圾回收器时,不会再次调用SetFinalizer 看到obj无法访问,它将释放obj。
终结器运行一个对象,以检查它是否无法从源到达。它可以用于文件描述符,但是依靠终结器来刷新内存中的I / O缓冲区(例如bufio.Writer)将是一个错误,因为该缓冲区不会在程序退出时被刷新。