语言的内存管理是语言设计的一个重要方面. 它是决定语言性能的重要因素. 无论是 c语言 的手工管理, 还是 Java 的垃圾回收, 都成为语言最重要的特种.

以下以 python 为例, 说明一门动态语言类型的, 面向对象的语言的内存管理方式.

  1. 对象的内存使用
    赋值语句
`a = 1`

 数字 1 是一个对象, a 是一个引用. 利用赋值语句, 引用 a 指定对象 1 .

python 是动态类型的语言, 引用与对象分离.

id() 返回对象的内存地址.

在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。当我们创建多个等于1的引用时,实际上是让所有这些引用指向同一个对象。

使用 is 判断引用所指向的对象是否相同 : 
     a = 1
     b = 1
     a is b

在Python中,每个对象都有存有指向该对象的引用总数,即引用计数(reference count)。

使用 sys.getrefcount() 来查看某个对象的引用计数.

 *当使用某个引用作为参数,传递给getrefcount()时,参数实际上创建了一个临时的引用。因此,getrefcount()所得到的结果,会比期望的多1。*
     from sys import getrefcount

     a = [1, 2, 3]
     print(getrefcount(a))   # 2

     b = a
     print(getrefcount(a))   # 3
     print(getrefcount(b))   # 3
  1. 对象引用对象
    python 中的 容器对象(container) 比如 表, 字典等, 可以包含多个对象. 实际上, 容器对象中包含的并不是元素对象本身, 是指向各个元素对象的引用.
    对象引用对象是 python 最基本的构成方式. 即使是 a=1 这一赋值方式, 实际上是让字典的一个键 "a" 的元素引用整数对象. 该字典对象用于记录所有的全局引用.
globals()  # 查看全局引用字典.
  1. 垃圾回收
    从基本原理上,当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。比如某个新建对象,它被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。
    垃圾回收时, Python 不能进行其他的任务. 频繁的来及回收将大大降低 python 的工作效率. 如果内粗怒中的对象不多就没有必要启动垃圾回收. 所有 python 只会在特定条件下, 自动启动垃圾回收. 当 python 运行时, 会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数, 当两者的差值高于某个阈值时, 启动垃圾回收.
    查看 阈值 :
import gc
 print gc.get_threshold()    # (700, 10, 10)

 gc.set_threshold(700, 10, 5)          # 设置 阈值.
 
 gc.collect()                # 手动启动垃圾回收.

 返回 (700,10,10) 中, 后面的 两个 10 与 分代回收相关的阈值, 700 为垃圾回收启动的阈值.
  1. 分代回收
    Python 同时采用 分代(generation) 回收的策略.
    分代回收的基本假设 : 存活时间越久的对象, 越不可能在后面的程序中变成垃圾.
    我们的程序往往会产生大量的对象, 许多对象很快产生和消失, 但也有一些对象长期被使用. 出于信任和效率, 对于这样一些 "长寿" 的对象, 我们相信他们的用处, 所以减少在垃圾回收中扫描他们的频率.
    Python 将所有的对象分为 0,1,2 三代. 所有的新建对象都是 0 代对象. 当某一代对象经历过垃圾回收, 依然存活, 那么, 他就被归为下一代对象. 垃圾回收启东时, 一定会扫描所有的 0 代对象. 如果 0 代经过一定次数垃圾回收, 那么就启动对 0 代和 1 代的扫描清理. 当 1 代也经历了一定次数的垃圾回收, 那么启动对 0,1,2 , 即所有对象进行扫描. 这两个 次数 就是上面 get_threshold() 返回的 (700,10,10) 后面的两个10, 即 每 10 次 0 代垃圾回收, 会配合 1 次 1 代的垃圾回收, 而每 10 次 1 代的垃圾回收, 才会有 1 次 2 代垃圾回收. 可以通过 gc.set_threshold() 来调整.
    Python采取了一种相对简单的垃圾回收机制,即引用计数,并因此需要解决孤立引用环的问题。