函数里打开文件没手动关闭,等函数执行完成自动回收会有什么问题?
发现之前写的一个日志类打开文件后没关闭,实际运行中没发现问题。
func (a *Loger) InfoLog(wireteString string,extfilename string){
var f *os.File
var err error
var filename = "info_"+extfilename + getCurDate()+".log"
if checkFileIsExist(a.path+filename) { //如果文件存在
f, err = os.OpenFile(a.path+filename, os.O_APPEND|os.O_WRONLY, os.ModeAppend) //打开文件
//fmt.Println("文件存在");
}else {
f, err = os.Create(a.path+filename) //创建文件
//fmt.Println("文件不存在");
}
check(err)
wireteString = wireteString+"\r\n"
_,err = io.WriteString(f, wireteString) //写入文件(字符串)
check(err)
//格式化用的日期是特定的,123 ( 15 ) 45 -.-lll
now_time := time.Now().Format("2006-01-02 15:04:05")
io.WriteString(f, now_time+"\r\n") //写入文件(字符串)
//fmt.Printf("写入 %d 个字节", n);
return
}
1
lsp7572 2021-06-15 11:28:59 +08:00
"实际运行中没发现问题"是啥意思,你这里没关闭已经句柄泄漏了吧。但是这个是潜在的问题,你随便运行下确实不会发现问题,但是上时间跑就会有问题
|
2
jasonkayzk 2021-06-15 11:39:55 +08:00
如果只有不超过一百个人用你的服务,代码写成屎也无所谓;
如果有超过一百万个人用你的服务,代码写出花也会出问题; |
3
Nitroethane 2021-06-15 12:08:58 +08:00 2
当 GC 运行的时候打开的文件确实会被关闭,但显式调用 Close 方法比 GC 自动处理更好。Stack overflow 上有相关的回答 https://stackoverflow.com/a/58351400/6628963
|
4
dongtingyue OP @lsp7572 运行很长时间了,逻辑上存在上百次打开同一文件进行写入的情况。所以就想是不是这个函数调用结束 gc 会自动进行句柄回收,不仅是局部变量的回收,文件相关的也会自动关闭。
|
5
dongtingyue OP @Nitroethane thx
|
6
no1xsyzy 2021-06-16 13:09:08 +08:00
golang gc 不是确定行为,它会独立决定何时运行(但我的知识有点古,不知道现在 STW 问题解决了没)。
Python 倒是有引用计数归零强制 gc 这一行为(因为老代码依赖这一行为,所以尽管后来实现了更好的可以避免循环引用的 gc 还是保留引用归零触发 gc ) ponylang 的 gc 流程(如同该语言下的一切,)是一种确定行为,但具体行为我不清楚,而且随版本更新可能快速发生改变。至少函数不结束根本不会触发 gc,就是一个 for 循环都直接导致暂时性泄漏。 |