Go语言默认情况下会对哪些对象进行终结操作,并且有哪些潜在问题?

huangapple go评论81阅读模式
英文:

Which objects are finalized in Go by default and what are some of the pitfalls of it?

问题

函数<code>runtime.SetFinalizer(x, f interface{})</code>将与<code>x</code>关联的终结器设置为<code>f</code>。

默认情况下,哪些对象会被终结?

由于默认情况下这些对象被终结,会导致哪些意外的问题?

英文:

The function <code>runtime.SetFinalizer(x, f interface{})</code> sets the finalizer associated with <code>x</code> to <code>f</code>.

What kind of objects are finalized by default?

What are some of the unintended pitfalls caused by having those objects finalized by default?

答案1

得分: 11

以下对象默认情况下会被终结:

  • 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()

    // 强制终结不可达对象
    _ = make([]byte, 1e7)
    runtime.GC()

    _, err := fmt.Println("some text") // 通过os.Stdout打印一些内容
    if err != nil {
        fmt.Fprintln(os.Stderr, "could not print the text")
    }
}

输出:

could not print the text
英文:

The following objects are finalized by default:

  • os.File: The file is automatically closed when the object is garbage collected.

  • os.Process: Finalization will release any resources associated with the process. On Unix, this is a no-operation. On Windows, it closes the handle associated with the process.

  • On Windows, it appears that package net can automatically close a network connection.

The Go standard library is not setting a finalizer on object kinds other than the ones mentioned above.

There seems to be only one potential issue that may cause problems in actual programs: When an os.File is finalized, it will make a call to the OS to close the file descriptor. In case the os.File has been created by calling function os.NewFile(fd int, name string) *File and the file descriptor is also used by another (different) os.File, then garbage collecting either one of the file objects will render the other file object unusable. For example:

package main

import (
    &quot;fmt&quot;
    &quot;os&quot;
    &quot;runtime&quot;
)

func open() {
    os.NewFile(1, &quot;stdout&quot;)
}

func main() {
    open()

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

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

prints:

could not print the text

答案2

得分: 5

只需返回翻译好的部分,不要有别的内容:

当go运行GC时,它会运行绑定在该对象上的Finalizers。
当你打开一个新文件时,go库会为你在返回的对象上绑定一个Finalizer。
当你不确定GC会对该对象做什么时,跳转到源代码并检查库是否在该对象上设置了一些finalizers。

英文:

Just jump into the os.NewFile's source code:

// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd uintptr, name string) *File {
    fdi := int(fd)
	if fdi &lt; 0 {
    	return nil
	}
    f := &amp;File{&amp;file{fd: fdi, name: name}}
	runtime.SetFinalizer(f.file, (*file).close)  // &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
	return f
}
  • When go runs GC, it will run Finalizers bind on that object.
  • When you open a new file, the go library will bind a Finalizer on that returned object for you.
  • When you are not sure what the GC will do to that object, jump to source code and check whether the library has set some finalizers on that object.

答案3

得分: -4

什么样的对象默认情况下会被终结?在Go语言中,我认为没有任何对象会默认被终结。

由于上述原因,没有任何意外的陷阱会因为这些对象默认被终结而产生。

英文:

"What kind of objects are finalized by default?"
Nothing in Go is IMO finalized by default.

"What are some of the unintended pitfalls caused by having those objects finalized by default?"
As per above: none.

huangapple
  • 本文由 发表于 2011年12月22日 03:49:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/8595457.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定