python属于动态语言,我们可以随意的创建和销毁变量,那么如果频繁的创建和销毁则会浪费cpu,那么python内部是如何优化的呢?
python和其他很多高级语言一样,都自带垃圾回收机制,不用我们去维护,也避免了出现内存泄漏,悬空指针等bug,那么python内部如何进行垃圾回收的呢?
python的垃圾回收,我们用gc模块去开启或者关闭它,那么gc模块又是什么呢?
python的优化机制
垃圾回收
关于循环引用进行一个测试
import gc # python的一个垃圾回收模块,garbage collection class A(object): def __init__(self): pass def foo(): while True: a1 = A() a2 = A() a1.t = a2 a2.t = a1 del a1 del a2 gc.disable() foo() ‘‘‘ 当我们使用gc.disable(),就意味着我们把python的垃圾回收机制给关闭了,那么一些垃圾便不会被自动回收。 首先我们创建了两个实例对象a1和a2,然后在a1的内部创建一个属性指向a2,在a2的内部创建一个属性指向a1 那么a1和a2的引用计数都为2,即使del a1,del a2,它们的引用计数还是为1,因此仍然会待在内存里不会被回收 当我们进行第二轮循环的时候,会继续再内存中创建一份a1和a2,不断地循环会发现程序所使用的内存也来越大,直至溢出崩溃 ‘‘‘
探讨一下ruby和python的垃圾回收机制ruby和python均属于脚本语言,它们是非常相似的,比方说定义两个类
ruby的对象分配当我们执行上面的Node.new(1)时,ruby在内部给我们做了什么?ruby是如何创建新的对象的呢?其实ruby做的很少,实际上早在代码执行之前,ruby就创建了成百上千个对象(类似于python的小整数对象池),并把它们串在链表上,叫做可用链表因此在创建对象的时候直接拿来用就可以了。
白色的小方格相当于标着一个“未使用预创建对象”,当我们调用Node.new方法时,ruby直接取出一个给我们使用即可
可以简单地理解,黑色格子是当前使用的对象,白色格子是未使用对象。当我们创建了一个“ABC”,放在了第一个格子的位置,让n1这个变量指向它。
由于这是一个链表,链表上的对象一般保存着下一个对象的内存指针,因此我们只需要找到一个便可以顺藤摸瓜将剩下的全给找出来,由于已经被使用,那么“箭头”也被切断了,剩下的白色格子在一个链表上,保存的是可用的内存
如果我们再次调用Node.new,ruby将继续递给我们一个对象。
因此随着我们不断地创建,ruby不断的从可用链表里取预创建对象给我们,从而也就导致了可用链表会越来越短
注意图像,我为n1不止赋了一次值,赋完值之后,又给n1赋了新的值,让n1指向了新的内存空间,那么就会有垃圾产生。
ruby的标记--清除
当我们把可用空间全部用完了,可用链表上变得空空如也
可以看到所有格子都变灰了,没有白格子了。那么ruby是如何解决这一问题的呢?
ruby使用的是标记--清除,首先ruby会把程序停下来,然后轮询所有的指针,变量和代码产生的别的引用对象以及其他值,同时ruby通过自身的虚拟机遍历内部指针,只要对象被引用,那么便将其标记(mark)出来。
只要没有被标记的,那么便是垃圾。
ruby将这些没有被标记的垃圾进行回收,并把它们送回到可用链表当中。
由于内部发生的很快,ruby不会将对象到处拷贝,而是通过调整内部的指针,将其指向一个新链表的方式,来将垃圾对象归位到可用链表当中的。
python的对象分配的的
原文地址:https://www.cnblogs.com/traditional/p/9205300.html