V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dongtingyue
V2EX  ›  Go 编程语言

函数调用变量自动回收问题

  •  
  •   dongtingyue · 2021-06-15 10:45:53 +08:00 · 1425 次点击
    这是一个创建于 1282 天前的主题,其中的信息可能已经有所发展或是发生改变。

    函数里打开文件没手动关闭,等函数执行完成自动回收会有什么问题?
    发现之前写的一个日志类打开文件后没关闭,实际运行中没发现问题。

    
    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
    }
    
    6 条回复    2021-06-16 13:09:08 +08:00
    lsp7572
        1
    lsp7572  
       2021-06-15 11:28:59 +08:00
    "实际运行中没发现问题"是啥意思,你这里没关闭已经句柄泄漏了吧。但是这个是潜在的问题,你随便运行下确实不会发现问题,但是上时间跑就会有问题
    jasonkayzk
        2
    jasonkayzk  
       2021-06-15 11:39:55 +08:00
    如果只有不超过一百个人用你的服务,代码写成屎也无所谓;
    如果有超过一百万个人用你的服务,代码写出花也会出问题;
    Nitroethane
        3
    Nitroethane  
       2021-06-15 12:08:58 +08:00   ❤️ 2
    当 GC 运行的时候打开的文件确实会被关闭,但显式调用 Close 方法比 GC 自动处理更好。Stack overflow 上有相关的回答 https://stackoverflow.com/a/58351400/6628963
    dongtingyue
        4
    dongtingyue  
    OP
       2021-06-16 09:39:32 +08:00
    @lsp7572 运行很长时间了,逻辑上存在上百次打开同一文件进行写入的情况。所以就想是不是这个函数调用结束 gc 会自动进行句柄回收,不仅是局部变量的回收,文件相关的也会自动关闭。
    dongtingyue
        5
    dongtingyue  
    OP
       2021-06-16 09:40:28 +08:00
    no1xsyzy
        6
    no1xsyzy  
       2021-06-16 13:09:08 +08:00
    golang gc 不是确定行为,它会独立决定何时运行(但我的知识有点古,不知道现在 STW 问题解决了没)。
    Python 倒是有引用计数归零强制 gc 这一行为(因为老代码依赖这一行为,所以尽管后来实现了更好的可以避免循环引用的 gc 还是保留引用归零触发 gc )
    ponylang 的 gc 流程(如同该语言下的一切,)是一种确定行为,但具体行为我不清楚,而且随版本更新可能快速发生改变。至少函数不结束根本不会触发 gc,就是一个 for 循环都直接导致暂时性泄漏。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3335 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:26 · PVG 19:26 · LAX 03:26 · JFK 06:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.