Какие объекты финализируются в Go по умолчанию и каковы некоторые из них? - PullRequest
6 голосов
/ 21 декабря 2011

Функция <a href="http://golang.org/pkg/runtime/#SetFinalizer" rel="noreferrer">runtime.SetFinalizer</a>(x, f interface{}) устанавливает финализатор, связанный с x, на f.

Какие объекты финализируются по умолчанию?

Каковы некоторые непреднамеренные ловушки, вызванные завершением этих объектов по умолчанию?

Ответы [ 3 ]

8 голосов
/ 21 декабря 2011

По умолчанию финализируются следующие объекты:

  • os. Файл : файл автоматически закрывается при сборке мусора.

  • os. Процесс : Финализация освободит все ресурсы, связанные с процессом.В Unix это не операция.В Windows закрывается дескриптор, связанный с процессом.

  • В Windows выясняется, что пакет <a href="http://golang.org/pkg/net/" rel="noreferrer">net</a> может автоматически закрывать сетевое соединение.

Стандартная библиотека 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
3 голосов
/ 08 апреля 2015

Просто перейдите к исходному коду 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
}
  • Когда Go запускает GC, он запускает привязку Финализаторов для этого объекта.
  • Когда вы открываете новый файл, библиотека go свяжет Финализатор с этим возвращенным объектом для вас.
  • Если вы не уверены, что GC сделает с этим объектом, перейдите к исходному коду и проверьте, не установила ли библиотека некоторые финализаторы для этого объекта.
0 голосов
/ 22 декабря 2011

«Какие объекты финализируются по умолчанию?»
Ничто в Go не является IMO финализированным по умолчанию .

"Что такоенекоторые непреднамеренные ловушки, вызванные завершением этих объектов по умолчанию? "
Как указано выше: нет.

...