与非网@你知道程序的“肾”是什么吗?( 二 )


同时引用计数法法有一个非常大的缺点 , 就是循环引用会导致内存泄漏 。 如下代码:
与非网@你知道程序的“肾”是什么吗?
文章图片
当函数执行完毕 , a与b相互引用 。 但是在栈中以及在数据段中已经没有指针可以访问到a与b的对象本身 。 也就是说程序已经失去了这两块内存的访问权 , 但是它们两者又相互指向 , 导致内存的计数无法归零 。 所以一直不能释放 , 导致了内存泄漏 , 形成了垃圾 。
二、可达性分析法 。
可达性分析法 , 顾名思义就是分析内存程序能否可以“达到” 。 也就是分析程序是否有失去对于内存的访问权 。 程序在运行状态中 , 内存时刻处于变化之中 , 犹如人体的血液流动不止 。 但是不管在任何时刻 , 我们的程序一定可以访问的内存大概有2个类别:
1、数据段 , 也就是全局变量与静态变量 。
2、栈空间中未释放的变量也就是当前入栈的动态局部变量 。
可达性分析法需要依赖于Runtime,也就是运行时环境 , 它们时刻监控着上面两个大类内存中的指针变量或者引用 , 并且周期性地对这些指针或者引用的指向进行遍历 , 并且是递归逐级地往下遍历 。 整体而言是在遍历一个以这两大类内存中的指针变量和引用为入口的图 。 只要能够遍历到的内存块就可以进行可达性的标志 。 当程序进入垃圾回收周期 , 它会遍历已经分配的所有内存 , 如果访问到的内存块拥有可达性标志 , 那么则跳过 。 如果没有可达性标志 , 则可以释放回收 。 这样就可以避免类似引用计数算相互引用导致不归零 , 但是不可达却又不释放的问题 。 如下图 , 蓝色内存块是会被回收的 。
与非网@你知道程序的“肾”是什么吗?
文章图片
然而 , 可达性分析算法是需要依赖于运行时环境的 , 也就是类似java那样的虚拟机 。 所以目前C/C++之类的语言还无法支持这种自动垃圾回收的判定算法 。
所以说了那么多 , 我们对于这些程序语言的一个诊断是:
OC:apple给它换了肾 , 但是肾不好 , 不过总体无碍 。
java:肾很好啊 。
C/C++:没有肾的 , 需要程序员帮他做“肾透析” 。
那么像C/C++这么好的语言 , 我们能够给它一个“肾” , 让它过上更加健康的生活吗?
【与非网@你知道程序的“肾”是什么吗?】答案是有的 。


推荐阅读