Golang语言--资源自动回收技术

Go语言作为一个现代化的编程语言以及支持垃圾内存的自动回收特性(GC). 我们现在关注的是非内存资源的自动回收技术.

局部资源的管理

在讨论Go语言解决方案之前, 我们先看看C++是怎么管理资源的.

C++中可以可以自动执行的代码主要是构造函数和析构函数. 因此, 很多资源的管理技术都是基于构造函数和析构函数实现.

比较常见的是C++的RAII(Resource Acquisition Is Initialization)技术, 即初始化中获取资源. 比如在多线程编程中用到的MutexLocker:

这样在使用Mutex的时候就不会忘记解锁的操作了:

其实RAII中最重要的是退出locker作用域是自动执行对象的析构函数, 这里也就是mu_->Unlock();语句.

C++的构造函数其实是次要的. 关于禁用C++构造函数的讨论可以参考我的 另一个文章: C++去掉构造函数会怎么样?

因为构造函数经常是通过显示定义变量而隐式调用的, 因此用普通的全局函数也 可以实现构造函数的功能(唯一的约束是值容器). 其实C语言的fopen就是一个FILE对象的构造函数.

而作为C语言简约哲学继承者的Go语言同样也没有对构造函数做特殊处理. 在Go语言中构造函数这是约定以New开头的普通函数, 比如NewBuffer.

Go语言/UNIX之父Ken Thompson发明了defer语句, 完美地 解决了析构函数的问题(defer还有很多其他特性).

因此, 在释放局部资源时, 可以用defer管理. 因为C++的RAII的构造 函数和析构函数耦合过于紧密, 对于资源申请失败的问题就比较麻烦. 但是Go语言的defer则灵活很多.

比如, Go语言版本基于deferMutex用法

对于可能申请失败的资源也很好处理:

使用defer语句, 可以方便地组合函数/闭包和资源对象. 即使panic时, defer也能保证资源的正确释放.

非局部资源的管理

我们之前看到的都是在局部使用和释放资源. 如果资源的生命周期很长, 而且可能被多个模块共享和随意传递的话, defer语句就不好处理了.

解决的思路和C++的RAII的方式类似: 我们需要一个能够自己定义的类似 析构函数的技术.

但是因为Go语言有GC特性, 因此没有析构函数的概念. 不过runtime包的 func SetFinalizer(x, f interface{})函数可以提供类似的机制.

比如, 我们可以包装一个文件对象, 在没有人使用的时候能够自动关闭:

在使用runtime.SetFinalizer时, 需要注意的地方是尽量要用指针访问 内部资源. 这样的话, 即使*MyFile对象忘记释放, 或者是被别的对象无意中覆盖, 也可以保证内部的文件资源可以正确释放.

总结

Go语言是短小精悍的语言, 它的设计哲学来自UNIX和C语言的KISS原则. 但是Go语言的语法规范虽然很少(50+页), 但是却提供了无限可能的组合方式.

Go语言之父Rob Pike有篇文章叫 少是指数级的多. 但是为什么少就是多呢?

参考下数学公理就明白了: 数学的基础规则是很简单的, 但是组合方式却是无穷的. Go语言的思路也是提供虽然少但却是正交的基础特性, 通过不同特性的无穷的 组合方式来应对各种问题(一个反例就是C++的构造函数和析构函数).

这里我们主要是基于Go语言的deferruntime.SetFinalizer两个基础特性, 来解决资源的自动回收问题.

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2016-05-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏owent

C++ 新特性学习(一) -- 概述+智能指针(smart_ptr)

C++ 0x/11 终于通过了,真是个很爽的消息。于是乎我决定对新的东西系统学习一下。

801
来自专栏Java后端技术栈

关于Java代码优化的N条建议!

本文是作者:五月的仓颉 结合自己的工作和平时学习的体验重新谈一下为什么要进行代码优化。在修改之前,作者的说法是这样的:

1122
来自专栏Brian

Python进阶教程(一)

概述 hi,朋友们大家好,今天将英文原著作者 @yasoob《Intermediate Python》进行翻译和在工作中使用的Python技巧进行了总结。Git...

3627
来自专栏恰同学骚年

【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱

  一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力。因为是...

682
来自专栏java工会

导致程序崩溃的一行代码,你有写过吗?

初学编程时,可能经常遇到一些程序崩溃的现象。一般来说,程序崩溃由于操作不当引起的。但是有时候,因为一个程序员的粗心,正式版本的程序出现崩溃状况这就很不因该了。之...

962
来自专栏difcareer的技术笔记

Android智能指针

网上已经有很多分析智能指针的文章了,讲得不错的是:Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析。本文尽量从不分析代码的角度,将And...

784
来自专栏微信公众号:Java团长

10个最受欢迎的Java类

每一个Java程序员都有一份属于自己的Java类排名表。这个排名表没有严格的规定,也没有可遵循的规则,它完全取决于你参与的Java项目的工作。下面这些类,不用我...

1152
来自专栏项勇

笔记45 | 代码性能优化建议[转]

1336
来自专栏做全栈攻城狮

程序员带你十天快速入门Python,玩转电脑软件开发(四)

本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结。本篇文章主要是基于上一篇的程序员带你十天快速入门Pyth...

832
来自专栏owent

“C++的90个坑”-阅读笔记

C++确实是一门复杂的语言。包括之前查看了一些C++11的文档和做了一些实践和总结,越来越觉得C++是门神奇的语言,也是个陷阱多多的语言。 我现在开发过程中最...

731

扫码关注云+社区