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 ensp的问题(需要各个路由器命令)
  • ¥15 Matlab怎么求解含参的二重积分?
  • ¥15 苹果手机突然连不上wifi了?
  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用
  • ¥15 kafka topic 所有分副本数修改
  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?
  • ¥40 串口调试助手打开串口后,keil5的代码就停止了
  • ¥15 电脑最近经常蓝屏,求大家看看哪的问题