什么是程序和控制算法有哪些,两个项目中哪些部分需要程序设计?

设计一个计算1×3×5×7×9×11×13的算法.图中给出了程序的一部分,则在横线①上不能填入的数是(  )A.13B.13.5C.14D.14.5【考点】.【专题】图表型.【分析】分析程序中各变量、各语句的作用,再根据流程图所示的顺序,可知:该程序的作用是累加并输出S的值.【解答】解:程序运行过程中,各变量值如下表所示:第1圈:S=1×3,i=5,第2圈:S=1×3×5,i=7,第3圈:S=1×3×5×7,i=9,第4圈:S=1×3×5×…×9,i=11,第5圈:S=1×3×5×…×11,i=13,第6圈:S=1×3×5×…×13,i=15,退出循环其中判断框内应填入的数要大于13且小于等于15,则在横线①上不能填入的数是选A,故选A.【点评】本题考查循环语句.解决程序框图中的循环结构时,常采用写出前几次循环的结果,从中找出规律.声明:本试题解析著作权属菁优网所有,未经书面同意,不得复制发布。答题:lily2011老师 难度:0.72真题:6组卷:29
解析质量好中差各种编程语言的实现都采用了哪些垃圾回收算法?这些算法都有哪些优点和缺点?
按投票排序
最近在看mruby的GC,传统的三色收集,有趣的地方是提供了一个分代模式,基本上完全重用三色收集的基础设施没加几行代码。(貌似从lua山寨来的? 三色收集来自dijistra的三色图遍历算法,将GC的mark与sweep均摊到多次渐进片段中,虽然简单,但其可贵之处在于能够确保正确性。然而将一个GC周期拉得较长,内存消耗会多一些。分代收集是历史经验选择出来的优生品,可以视为最经考验的GC算法。"老的对象活得更长,新的对象死的快" 是基本思想,将老的对象移动到记忆集里,每一轮minor GC只mark-sweep新对象,一轮minor GC之后存活得对象就被当成老对象,慢慢得老对象会遗留得越来越多,超过某一阙值之后会触发依次major GC,这时摘掉所有老对象的免死金牌,搞一轮大清理。相对三色GC和传统GC的好处是GC周期缩短,内存消耗少一点。优化的实现会复杂一些?(也可以反过来说优化的空间更大)mruby三色GC中分代模式的实现就是,黑色对象=老对象,mark阶段不标记它。到触发老对象的数量的阙值时,把所有黑对象再变回白色跑一轮完整GC。三色GC与分代GC都需要维护一个write barrier(跟乱序执行那个内存栅栏完全是无关的两码事),当黑色对象(或者老对象)有添加新对象的引用时,GC必须对此有所处理。对于扩展的开发者而言,这是一个需要小心注意的地方。lua和mruby都需要维护对象的引用关系,属于严格式GC。cruby与之相对,采用了保守式GC,传统的mark-sweep。好处是不需要write barrier,C结构体里直接引用ruby对象,提高了C扩展开发者的生活质量,不然现在绝对不会有这么多好用的gem。缺点搞过rails的同学都懂的,而且给gc的设计者挂了个大脚镣,以后优化起来得想更多办法吧。原则上保守式GC可以为C/C++提供垃圾收集的支持。按指针的宽度遍历栈,调用 is_point_to_heap() 猜这条指针是否指向堆(就一个简单的判断看看这个值是不是在堆的地址的范围之内),如果有个数值恰好跟堆里的指针的值一样,那么只能将哪个位置的对象mark掉了。如果碰巧这个对象是一大堆对象的根,那么恭喜,内存会很吃亏了。boehm对于这种情况有所研究,出了一个算法可以减少这种误判(书上看的,详细不知道了)。它就只暴露了malloc()和free()两个接口,C程序员可以很轻松利用它到现有项目中。为了捕获write barrier同时不引入额外的接口,印象中它严重地依赖写保护和页面错误。cruby和mruby的堆是个偷懒的实现,维护两个堆,一个对象堆,一个系统堆。ruby的所有对象的大小都相同,使得对象堆看起来有点像slab。以字符串对象为例,它会保存字符串的长度,和一个指向系统堆的字符串内容的指针,系统堆中的字符串的内容的生命周期与对象堆中的字符串对象保持一致。ree与cruby2.0的gc对于写时复制友好下了很大功夫,可以说这个特性这跟ruby的应用场景息息相关。在web服务器中,fork一个进程的实例之后,如果跑一轮GC,就会写遍所有对象,堆里所有的写保护的页面都会失效,不得不触发写时复制,吃掉 (进程数*堆大小) 的物理内存。nari和matz的方案是移除对象中的标记位,统一挪到堆的头部搞成一个bitmap。这样在mark阶段,所有的写都会集中到这个bitmap上,原则上只会触发少数几次写时复制,可以省不少内存。
垃圾收集算法是个很大的话题。首先要明确的是,垃圾收集算法和语言不一定是绑定的。比如 Java,不同的 JVM 实现可能采用不同的算法。其次,垃圾收集算法数量庞大,一一列举是不可能的,篇幅所限这里只能给个非常概略的介绍。如果希望对垃圾收集相关算法有个全景式的了解,请参阅本人的译作,。==== 转入正文的分割线 ====从各种垃圾收集算法最基本的运行方式来说,大概可以分成三个类型:1. 引用计数(reference counting):基本思路是为每个对象加一个计数器,记录指向这个对象的引用数量。每次有一个新的引用指向这个对象,计数器加一;反之每次有一个指向这个对象引用被置空或者指向其他对象,计数器减一。当计数器变为 0 的时候,自动删除这个对象。引用计数的优点是 1)相对简单,不需要太多运行时(run-time)的支持,可以在原生不支持 GC 的语言里实现。2)对象会在成为垃圾的瞬间被释放,不会给正常程序的执行带来额外中断。它的死穴是循环引用,对象 A 包含一个引用指向对象 B ,同时对象 B 包含一个引用指向对象 A,计数器就抓瞎了。另外,引用计数对正常程序的执行性能有影响(每次引用赋值都要改计数器),特别是在多线程环境下(改计数器要加锁同步)。现在仍然主要采用引用计数的例子有 Apple 的 ARC,C++ 新标准里的 std::shared_ptr。2. 标记-清扫(mark-sweep)。基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。标记-清扫没有无法处理循环引用的问题,不触发 GC 时也不影响正常程序的执行性能。但它的问题是当内存耗尽触发 GC 时,需要中断正常程序一段时间来清扫内存,在内存大对象多的时候这个中断可能很长。采用或者部分采用标记-清扫的例子非常多,不一一列举了。3. 节点复制(copying)。基本思路是把整个内存空间一分为二,不妨记为 A 和 B。所有对象的内存在 A 中分配,当 A 塞满的时候,同样从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象复制到 B 去,然后对调 A 和 B 的角色。相对于标记-清扫,节点复制的主要缺点是总有一半空间空闲着无法利用,另一个比较隐晦的缺点是它使用内存的方式与现有的内存换页、Cache 换入换出机制有潜在的冲突。但它有个很大的优点: 所有的对象在内存中永远都是紧密排列的,所以分配内存的任务变得极为简单,只要移动一个指针即可。对于内存分配频繁的环境来说,性能优势相当大。另外,由于不需要清扫整个内存空间,所以如果内存中存活对象很少而垃圾对象很多的话(有些语言有这个倾向),触发 GC 造成的中断会小于标记-清扫。同样的,采用或者部分采用节点复制的例子也非常多,不一一列举了。==== 基本算法介绍完毕的分割线 ====以上三种基本算法各有优缺点,也各有许多改进的方案。目前工程实践上最为成功的方案应该要算分代(generational)垃圾收集。它的基本思路是这样的:程序中存在大量的临时对象,分配出来之后很快就会被释放,而同时如果一个对象分配出来之后相当长的一段时间内都没回收,那么极有可能它的生命周期很长,尝试收集它会是无用功。所以可以把内存有意识地按“对象年龄”分成若干块,不妨记为老中青(XD),所有的分配都在青代进行,青代塞满只对青代做 GC,然后把存活下来的对象移动到中代,直到中青代都塞满,再把存活下来下来的对象移动到老代 —— 这只是个思路上的例子,实践中分代式垃圾收集算法的方案五花八门,而且常常同时使用了不止一种基本算法(比如青代用节点复制,老代用标记清扫啥的)。
我来回答下PHP的吧, 在5.3以前PHP采用经典的引用技术方法, 这种方法简单, 回收期分散, 不会造成程序的长时间挂起. 然而缺点就是不能解决循环引用. 这个问题对于PHP来说本身不是什么大问题, 因为经典的应用场景下, 一次请求结束以后, 所有属于这个请求的内存就会被释放. 但是随着PHP的应用场景越来越广, 一些后台脚本, 服务也开始需要用PHP来编写, 这样一来, PHP就需要解决循环引用问题.在PHP5.3的时候, 引入了一套额外的垃圾回收算法: &Concurrent Cycle Collectionin Reference Counted Systems & 作为对引用计数的一个补充, 这套新的逻辑叫做zend_gc.
具体实现可以参看:
有一本书介绍的挺详细的:Garbage Collection: algorithms for automatic dynamic memory management
贴一下之前的读书笔记,抛砖引玉。-------------------GC in python----------------------常见的GC算法常见的垃圾收集(garbage collection)算法主要有以下几种。引用计数(Reference Count)工作原理:为每个内存对象维护一个引用计数。当有新的引用指向某对象时就将该对象的引用计数加一,当指向该对象的引用被销毁时将该计数减一,当计数归零时,就回收该对象所占用的内存资源。标记-清除(Mark-Sweep)工作原理:分两个步骤,一是标记,即从众多的内存对象中区分出不会再被使用的垃圾对象;二是清除,即把标记的垃圾对象清除掉。标记的时候需要确定内存对象的集合Root set,集合里的对象都是可以访问的。如果Root set中的对象引用了其他的对象,那么被引用的对象也不能被标记为垃圾对象。然后从Root set出发,递归遍历Root set能访问到的所有对象,进行标记为不是垃圾对象。遍历结束后,没有被标记的就是垃圾对象。分代收集工作原理:根据一个统计学上的结论,如果一个内存对象在某次Mark过程中发现不是垃圾,那么它短期内成为垃圾的可能性就很小。分代收集将那些在多次垃圾收集过程中都没有被标记为垃圾对象的内存对象集中到另外一个区域——年老的区域,即这个区域中的内存对象年龄比较大。因为年老区域内内存对象短期内变成垃圾的概率很低,所以这些区域的垃圾收集频率可以降低,相对的,对年轻区域内的对象进行高频率的垃圾收集。这样可以提高垃圾收集的整体性能。2.
Python 中的内存管理在CPython中,大多数对象的生命周期都是通过对象的引用计数来管理的。引用计数是一种最直观、最简单的垃圾收集计数,与其他主流GC算法比较,它的最大优点是实时性,即任何内存,一旦没有指向它的引用,就会立即被回收。然而引用计数存在两个比较麻烦的缺陷:当程序中出现循环引用时,引用计数无法检测出来,被循环引用的内存对象就成了无法回收的内存,引起内存泄露。比如:list1 = []
list1.append(list1)
list1循环引用了自身,第二行执行完后,list1的GC变成了2,执行完del操作后,list1的引用计数变为1,并没有归零,list1的内存空间并没有被释放,造成内存泄露。维护引用计数需要额外的操作。在每次内存对象呗引用或者引用被销毁时都需要修改引用计数,这类操作被称为footprint。引用计数的footprint是很高的,使得程序的整体性能受到很大的影响。3.
补充为了解决循环引用的问题,CPython特别设计了一个模块——GC module,其主要作用就是检查出循环引用的垃圾对象,并清除他们。该模块的实现,实际上也是引入了前面提到的两种主流的垃圾收集技术——标记清除和分代收集。为了解决引用计数的性能问题,尽量再内存的分配和释放上获得最高的效率,Python因此还设计了大量的内存池机制。[ref]《Python源码剖析》
Luajit的维基有一篇很棒的关于垃圾收集算法的介绍 除了引用计数(COM也是用的这个,需要手动管理)之外,还有双色标记删除,三色增量式,四色优化增量式,分代式的等等。算法复杂了,不容易实现和维护,太简单的也许在某些场景性能不够好。DotNet平台用的是分代式,三代,最新的4.5在GC上尤其是服务器GC上性能有大幅改进,这个可以关注。Two-Color Mark & SweepTri-Color Incremental Mark & SweepQuad-Color Optimized Incremental Mark & SweepGenerational GC
推荐看一下松本行弘的《代码的未来》,其中的 “2.4 内存管理” 对GC有较详细的论述,并且也对几种不同编程语言的GC做了比较。补一下2.4的章节目录:2.4 内存管理 61 看似无限的内存 61 GC的三种基本方式 62 术语定义 62 标记清除方式 63 复制收集方式 64 引用计数方式 65 引用计数方式的缺点 65 进一步改良的应用方式 66 分代回收 66 对来自老生代的引用进行记录 67 增量回收 68 并行回收 69 GC大统一理论 69
Python的垃圾回收机制是通过引用计数来实现的。Python中所有的对象都有一个引用计数(Python源码中PyObject_HEAD宏里定义的ob_refcnt变量),每当有新的地方使用该对象就会增加它的引用计数(Python源码中的Py_XINCREF宏),反之则减少(Python源码中的Py_XDECREF宏),当引用计数减为0的时候会被销毁(不过相比释放该对象的内存空间,Python更多地采用把该对象的内存空间放到对应缓冲池中去的方法)。
感谢邀请。JVM 最新一代的GC,Garbage First,基本机制就是把堆划分为很多固定大小的region,每个region都有一个对应的remembered set结构,用来记录指向这个区域中的地址的其他区域的指针。 在垃圾回收时,选择记录最少的一个区域进行,按找这种方式选择出来的区域,通常是有用数据最少、垃圾最多的区域。将其中活跃的对象通过copy的方式复制到其他的区域中(准确说来会是old region,对于old region会有一定的几率进行回收)。这也就是“Garbage-first ”名称的由来。如此一来就可以以region为单位整区域回收内存(传统的GC是以单个对象内存为单位)。下面两篇文章都有详尽的描述:
从垃圾回收算法本身而言,Erlang没有什么特别的,全局层面用的分代gc,语言底层用的是mark-sweep以及引用计数gc。但是Erlang最大的特点是erlang轻量级进程的堆是完全私有的,变量是单次赋值不可变的,进程之间没有数据共享。考虑到erlang的高并发性,拥有上万个进程,挂起某个进程挨个来GC,其他进程不受影响,而且由于进程的堆比较小,所以可以在比较短的时间内完成。对于超过64字节的二进制数据,为了节省数据复制的开销,采用引用计数的共享堆,便于数据在进程间的传递,所以必须当引用计数清零才能释放数据。但是erlang的引用计数没有循环引用的问题,因为erlang的变量是单向赋值的,只存在进程变量对二进制数据的单向引用。从这里可以看出,不同的数据模型对于垃圾回收的影响有多大。
经提醒iOS没有传统意义上的垃圾回收机制 ARC是编译过程中对代码添加一些代码实现的内存管理的功能的在Xcode 4.2以前 是完全没有垃圾回收的 全部纯手动 主要就是通过一些函数来管理内存的基本概念Object-C 的内存管理基于引用计数(Reference Count)这种非常常用的技术。简单讲,如果要使用一个对象,并希望确保在使用期间对象不被释放,需要通过函数调用来取得“所有权”,使用结束后再调用函数释放“所有权”。“所有权”的获得和释放,对应引用计数的增加和减少,为正数时代表对象还有引用,为零时代表可以释放。获得所有权的函数包括alloc – 创建对象是调用alloc,为对象分配内存,对象引用计数加一。copy – 拷贝一个对象,返回新对象,引用计数加一。retain – 引用计数加一,获得对象的所有权。释放所有权的函数包括release – 引用计数减一,释放所有权。如果引用计数减到零,对象会被释放。autorelease – 在未来某个时机释放。下面具体解释。在某些情况下,并不想取得所有权,又不希望对象被释放。例如在一个函数中生成了一个新对象并返回,函数本身并不希望取得所有权,因为取得后再没有机会释放(除非创造出新的调用规则,而调用规则是一切混乱的开始),又不可能在函数内释放,可以借助autorelease 。所谓autorelease , 可以理解为把所有权交给一个外在的系统(这个系统实际上叫autorelease pool),由它来管理该对象的释放。通常认为交给 autorelease 的对象在当前event loop 中都是有效的。也可以自己创建NSAutoreleasePool 来控制autorelease的过程。据苹果的人说,autorelease效率不高,所以能自己release的地方,尽量自己release,不要随便交给autorelease来处理。规则引用计数系统有自己的引用规则,遵守规则就可以少出错:获得所有权的函数要和释放所有权的函数一一对应。保证只有带alloc, copy, retain 字串的函数才会让调用者获得所有权,也就是引用计数加一。在对象的 dealloc函数中释放对象所拥有的实例变量。永远不要直接调用dealloc来释放对象,完全依赖引用计数来完成对象的释放。有很多类都提供“便利构造函数(convenience constructors)”,它们创建对象但并不增加引用计数,意味着不需要调用release来释放所有权。很好辨认,它们的名字中不会有alloc和copy。只要遵守这些规则,基本上可以消除所有Intrument可以发现的内存泄露问题。容器类似NSArray, NSDictionary, NSSet 等类,会在对象加入后引用计数加一获得所有权,在对象被移除或者整个容器对象被释放的时候释放容器内对象的所有权。类似的情况还有UIView对subview的所有权关系,UINavigationController对其栈上的controller的所有权关系等等。其他所有权的产生还有一些用法会让系统拥有对象的所有权。比如NSObject 的performSelector:withObject:afterDelay 。如果有必要,需要显示的调用cancelPreviousPerformRequestsWithTarget:selector:object: ,否则有可能产生内存泄露。因这种原因产生的泄露因为并不违反任何规则,是Intrument所无法发现的。循环引用所有的引用计数系统,都存在循环应用的问题。例如下面的引用关系:对象a创建并引用到了对象b.对象b创建并引用到了对象c.对象c创建并引用到了对象b.这时候b和c的引用计数分别是2和1。当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。这种情况,必须打断循环引用,通过其他规则来维护引用关系。比如,我们常见的delegate往往是assign方式的属性而不是retain方式的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。如果一个UITableViewController 对象a通过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate又是a, 如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。以上摘自: 在新的Xcode 4.2 已经引入了ARC的机制 发现一篇介绍的比较好的文章 : 我就不重复劳动了
C#中用到的标记-压缩算法,把可达的对象标记出来,然后回收不可达对象,最后进行内存压缩。缺点是垃圾回收的算法可能影响程序的性能。由于回收一部分对象比回收全部对象性能提高和越来的对象生存期就越长,所有C#采用了代的概念,既如果第0代足够用,就不用去管第1代的对象,只回收第0代的对象。
我来回答一下VB吧,VB其实算不上有垃圾回收算法,至少在VB6的时代,是没有垃圾回收这一说的,但VB确实能回收一些资源,主要对于局部变量有效,当然,用户也可以手动释放,另外set nothing应该算是引用计数吧。手动释放:比如创建一个对象用createobject或者new关键字,就创建了这个对象,当用户使用set xxx=nothing的时候就释放了这个对象。所以VB要求全局对象必须用set xxx=nothing的方式显式释放。自动释放:这种一般用于局部变量,比如dim了一个变量,set xx= new xxxx,即使你不释放,函数(过程)走到头退出的时候,它就自动释放了。因为当你退出一个过程的时候,你申请的临时资源都会调用析构函数,资源就释放了。原理么,可以理解为类的概念,其实VB就是在MFC上封装了一层东西,内部的都是靠C的对象来维护的,那么new一个窗体,在它关闭以后,自然会有析构函数去处理,而默认不处理的局部内容,最后都会被vb默认撤销掉。不知道你对比过VC跟VB的代码没,有一个很有意思的特性,比如ADODB的recordset对象,在VB里是set rs=nothing来释放,VC里是RS=NULL,如果单步跟踪会发现VC里实际是重载了=这个运算符,调用的是析构函数。当然VB垃圾回收也有不好的地方,比如,你关闭了一个窗口,如果这个窗口是工程里添加的,不是你new出来的,那么这个窗口资源会一直存在,直到进程退出,原因还不太明白,也不知道后续会有什么改进。没怎么玩,改的太多了,已经不太VB了。再补充:多个变量是可以引用同一个对象的,比如定义一堆form类型的变量,都指向某个new出来的窗体,这是可以的,即使窗体关闭了也存在,因为引用技术不为0,只有所有的变量都set =nothing以后,那个窗体资源才会被真正释放。总结一下:1、通过引用计数,引用为0,自动释放;2、局部变量引用在失效时,自动调用set xxx=nothing;3、全局变量引用会一直存在,需要手动调用set xxx=nothing;就这么多吧
纵观GC的历史共有三种基本算法:1、标记清除:在此之上又有变形算法——标记压缩。在此之上又有变形算法——标记压缩。2、复制收集:复制收集利用两个内存区域,避免了标记清除算法在清楚阶段还需要遍历大量死亡节点的过程,减少了时间开支。3、引用计数3、引用计数所有对象保存着自己被别人引用的次数,减少一次,则自身减少1,同时自己引用的对象的引用计数也减少1。计数为0的为死亡节点可以释放。引用计数不需要遍历全部对象,实现最为简单。释放空间是立即释放。缺点是如果有循环引用(引用关系连成环了)则永远也释放不了,同时不适合并行处理。基于以上方法现代改良的GC算法:1、分代回收:基本假说:大部分新产生的对象会在较短时间内成了垃圾,而经过一定时间依然存活的对象一般寿命较长。依据此假说,那么只要扫描新生代的对象就可以实现大部分垃圾的回收。扫描新生代对象称为“小回收”,一般采用复制收集算法,另外为了加速扫描在扫描过程中如果遇到老生代对象,不递归扫描。然后将小回收剩下的对象划到老生代。如果有老生代对新生代的引用,则用一个记录集来实时记录,称为“写屏障”。小回收中,记录集也当做一个扫描“根”来对待。一定时候会对老生代,新生代一起进行一次“大回收”。实际上,很多语言的GC会设置好几代,而不是两代。2、增量回收:为了保持程序实时性,将一个GC不一次执行,而是分成多个小步骤在程序间隙分步执行。显然这种算法需要实时维护程序中对象的引用关系,在每一步骤执行时都需记录引用状态变更(即“写屏障”)。3、并行回收:充分利用多核,让GC并行在多核上进行回收,将占用程序运行的时间缩小到最小。GC大统一理论:IBM研究者说:任何一种GC算法都是引用计数和跟踪回收两种思路的组合。——以上,整理自松本行弘《代码的未来》目前来看,JAVA的GC是应用技术最多,同时也是性能最好的。
JavaScript的:标记清除 Mark and Swap: 为内存中存储的变量添加标记,比如进入环境,离开环境,删除某些标记而保留另外某些标记。引用计数 Reference count:记录引用的次数,被变量引用则加1,变量引用另外的值则减1,为0时可以被回收。
我来说一下Javascript的吧在C和C++之类的语言,开发人员的一项基本任务就是手工跟踪内存使用情况,内存必须手动地被释放。但在JS中,内存的分配及无用内存的回收实现了自动管理,这是JS的“垃圾收集”。Javascript的解释器可以检测到何时程序不再使用一个对象了。当它确定了一个对象时无用的时候(例如,程序中使用的变量再也无法引用这个对象了),它就知道不再需要这个对象,可以把它所占用的内存释放掉了。见如下示例代码:var s = "hello";var u = s.toUpperCase();s =运行了这些代码之后,就不能再获得原始的字符串"hello",因为程序中没有变量再引用它了。系统检测到这一事实后,就会释放该字符串的存储空间以便这些空间可以被再利用。垃圾收集是自动进行的,对程序员来说是不可见的。对于垃圾收集,唯一需要程序员做的就是相信它一定会起作用,程序员可以创建任何想要的无用对象,系统将会将它们都清除掉。关于JS“垃圾收集”更详细的算法和介绍请参考《Javascript高级程序设计(第二版)》P69-P72
各位的回答让我很长见识!谢谢!以前只知道java的垃圾回收机制。最近在写C++程序,感觉到字符串资源分配管理上还不够方便,就写了一个公共的字符串堆资源pool管理类,由它来实现分配和回收,重点是实现回收。使用者省掉了释放过程,这对有条件释放的时候方很方便。
python的垃圾收集
参考《python学习手册》第四版 158页 对象的垃圾收集对@李垚 的补充从技术上将,python的垃圾收集主要是基于引用计数器,如李垚所讲,然后它也有一部分功能是可以及时地检测并回收带有循环引用的对象,如果你确保自己的代码没有产生循环引用,这个功能是可以关闭的,但是默认的该功能是可用的。
补上Go语言的垃圾回收,Go在1.2之前用的是标记清扫算法,在1.3之后开始改进为并行的垃圾回收。别人的研究成果,在收藏夹里至今没仔细看过。希望有时间一定要恶补一下。
c,手工回收。}

我要回帖

更多关于 控制算法有哪些 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信