默认情况下哪些对象在Go中完成,有哪些陷阱?

时间:2011-12-21 19:49:11

标签: garbage-collection go finalizer

功能runtime.SetFinalizer(x, f interface{})将与x相关联的终结器设置为f

默认情况下最终确定了哪种对象?

默认情况下最终确定这些对象会导致哪些意外缺陷?

3 个答案:

答案 0 :(得分:8)

默认情况下,以下对象已完成:

  • os。File:当对象被垃圾收集时,文件会自动关闭。

  • os。Process:终结将释放与该过程相关的所有资源。在Unix上,这是一个无操作。在Windows上,它会关闭与进程关联的句柄。

  • 在Windows上,包net可以自动关闭网络连接。

Go标准库没有在上述对象类型之外设置终结器。

似乎只有一个可能导致实际程序出现问题的潜在问题:当os.File最终确定时,它将调用操作系统来关闭文件描述符。如果通过调用函数os.File创建了os.NewFile(fd int, name string) *File并且文件描述符也被另一个(不同的)os.File使用,则垃圾收集 之一文件对象将使另一个文件对象无法使用。例如:

package main

import (
    "fmt"
    "os"
    "runtime"
)

func open() {
    os.NewFile(1, "stdout")
}

func main() {
    open()

    // Force finalization of unreachable objects
    _ = make([]byte, 1e7)
    runtime.GC()

    _, err := fmt.Println("some text") // Print something via os.Stdout
    if err != nil {
        fmt.Fprintln(os.Stderr, "could not print the text")
    }
}

打印:

could not print the text

答案 1 :(得分:2)

只需跳转到 os.NewFile 的源代码:

// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd uintptr, name string) *File {
    fdi := int(fd)
    if fdi < 0 {
        return nil
    }
    f := &File{&file{fd: fdi, name: name}}
    runtime.SetFinalizer(f.file, (*file).close)  // <<<<<<<<<<<<<<
    return f
}
  • 当运行GC时,它将在该对象上运行Finalizers bind。
  • 当您打开一个新文件时,go库将为您返回该返回对象上的Finalizer。
  • 如果您不确定GC将对该对象执行什么操作,请跳转到源代码并检查库是否在该对象上设置了一些终结器。

答案 2 :(得分:-4)

“默认情况下最终确定了哪种对象?”
Go中的任何内容都不是IMO 默认

“默认情况下最终确定这些对象会导致哪些意外的陷阱?”
如上所述:无。