垃圾回收是否在使用之前释放存储在包级变量中的指针?

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

Does garbage collection free pointers stored in package-level variables before they are used?

问题

我有一个配置对象,它在启动时基于环境变量初始化一些变量:

// 在启动时初始化配置对象,并在出现环境问题时快速失败
_ = utils.GetConf()

这段代码位于我的服务器的init()方法中,在代码的其他地方,我只需调用GetConf()来获取配置对象。我想通过单例模式来实现这个配置对象:

import (
	"fmt"

	env "github.com/Netflix/go-env"
)

type Conf struct {
	DBName        string `env:"MONGO_INITDB_DATABASE,required=true"`
	Hostname      string `env:"HOSTNAME,required=true"`
	DBUsername    string `env:"MONGO_INITDB_ROOT_USERNAME,required=true"`
	DBPassword    string `env:"MONGO_INITDB_ROOT_PASSWORD,required=true"`
}

var gConf *Conf

func GetConf() *Conf {
	if gConf != nil {
		return gConf
	}
	gConf = new(Conf)
	_, err := env.UnmarshalFromEnviron(gConf)
	if err != nil {
		panic(err)
	}
	return gConf
}

由于我在启动时没有对utils.GetConf()的返回值做任何处理,是否有可能Go语言会对我的配置对象进行垃圾回收,导致gConf指针指向无效的内存地址?

英文:

I have a config object which initializes some variables based on environment variables at startup:

// init the conf object on startup and fail quickly if there's an environment issue
_ = utils.GetConf()

This is in the init() method of my server, and in other places in my code, I just call GetConf() to get the config object. I'd like to implement this config object through a singleton pattern:

import (
	"fmt"

	env "github.com/Netflix/go-env"
)

type Conf struct {
	DBName        string `env:"MONGO_INITDB_DATABASE,required=true"`
	Hostname      string `env:"HOSTNAME,required=true"`
	DBUsername    string `env:"MONGO_INITDB_ROOT_USERNAME,required=true"`
	DBPassword    string `env:"MONGO_INITDB_ROOT_PASSWORD,required=true"`
}

var gConf *Conf

func GetConf() *Conf {
	if gConf != nil {
		return gConf
	}
	gConf = new(Conf)
	_, err := env.UnmarshalFromEnviron(gConf)
	if err != nil {
		panic(err)
	}
	return gConf
}

Since I'm not doing anything with the return value of utils.GetConf() at the start, is it possible that golang will garbage collect my config object and my gConf pointer will end up pointing to nowhere?

答案1

得分: 4

如果你创建一个指向值的指针,解引用该指针将得到该值。

这是你必须记住的全部。垃圾回收系统可能在幕后做任何事情,但上述语句仍然必须保持真实。如果垃圾回收器在你使用指针之前使其无效,那将是语言的一个错误实现(即编译器错误)。

当对Go的工作方式有疑问时,始终请参阅Go语言规范。你会发现指针行为被明确定义。另一方面,垃圾回收只在介绍中提到,没有定义任何行为。因此,我们可以假设垃圾回收不应该覆盖或以其他方式干扰指针的工作方式。

英文:

If you create a pointer to a value, dereferencing that pointer will yield that value.

That is really all you must bear in mind. The garbage collection system may be doing whatever it's doing behind the scene, but the above statement must still remain true. If the garbage collector were to invalidate your pointers before you use them, that would be a broken implementation of the language (i.e., a compiler bug).

When in doubt about how Go works, always consult the Go language specification. You'll see that pointer behaviour is plainly defined. Garbage collection, on the other hand, is only mentioned in the introduction without defining any behaviour. Therefore, we can assume that garbage collection should not override or otherwise interfere with the way pointers are supposed to work.

huangapple
  • 本文由 发表于 2022年6月20日 07:34:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/72680978.html
匿名

发表评论

匿名网友

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

确定