douturan1807 2018-07-10 09:02
浏览 697
已采纳

是否需要关闭zip.NewReader(bytes.NewReader(),len)或自动垃圾回收?

I'm having an argument with a friend, over possible wasted resources in Go.

Does a Reader have to be closed, if it's operating over an in-memory byte array?

func readJar(zipBytes []byte, readMeta bool) (m jar.Manifest, err error) {
    reader, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
    if err != nil {
        return
    }

    for _, file := range reader.File {
        switch file.Name {
        case jar.ManifestPath:
            m, err = readManifest(file)
            if err != nil {
                return
            }
        }
    }
    return
}

func readManifest(file *zip.File) (jar.Manifest, error) {
    reader, err := file.Open()
    if err != nil {
        return nil, err
    }

    defer reader.Close()
    return jar.ReadManifest(reader)
}

Whilst originally it was thought to be a source of File Handle Leaks, something else got the blame.

Will this leak memory, or does Go have sufficient escape analysis / garbage collection that it will be fine?

  • 写回答

1条回答 默认 最新

  • duangang2825 2018-07-10 09:13
    关注

    Golang compiler takes care for unreachable variables:-

    The storage location does have an effect on writing efficient programs. When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame. However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors. Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack.

    Although Golang contains garbage collection. It would be better to use clean up functions. You can use defer function to close the file at the end of function.

    defer f.close()
    

    Check Documentation for SetFinalizer to get more understanding on these concepts:

    func SetFinalizer(obj interface{}, finalizer interface{})
    

    SetFinalizer sets the finalizer associated with obj to the provided finalizer function. When the garbage collector finds an unreachable block with an associated finalizer, it clears the association and runs finalizer(obj) in a separate goroutine. This makes obj reachable again, but now without an associated finalizer. Assuming that SetFinalizer is not called again, the next time the garbage collector sees that obj is unreachable, it will free obj.

    The finalizer runs for an object to check if it is unreachable from the source. It can be used for file descriptors but it would be a mistake to depend on a finalizer to flush an in-memory I/O buffer such as a bufio.Writer, because the buffer would not be flushed at program exit.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了