如何管理内存
内存是一种你不可以耗尽的珍贵资源。在一段时期里,你可以无视它,但最终你必须决定如何管理内存。
堆内存是在单一子程序范围外,需要持续(保留)的空间。一大块内存,在没有东西指向它的时候,是无用的,因此被称为垃圾。根据你所使用的系统的不同,你可能需要自己显式释放将要变成垃圾的内存。更多时候你可能使用一个有垃圾回收器的系统。一个垃圾回收器会自己注意到垃圾的存在并且在不需要程序员做任何事情的情况下释放它的内存空间。垃圾回收器是奇妙的:它减小了错误,然后增加了代码的简洁性。如果可以的话,使用垃圾回收器。
但是即使有了垃圾回收机制,你还是可能把所有的内存填满垃圾。一个典型的错误是把哈希表作为一个缓存,但是忘了删除对哈希表的引用。因为引用仍然存在,被引用者是不可回收但却无用的。这就叫做内存泄露。你应该尽早发现并且修复内存泄露。如果你有一个长时间运行的系统,内存可能在测试中不会被耗尽,但可能在用户那里被耗尽。
创建新对象在任何系统里都是有点昂贵的。然而,在子程序里直接为局部变量分配内存通常很便宜,因为释放它的策略很简单。你应该避免不必要的对象创建。
当你可以定义你一次需要的数量的上界的时候,一个重要的情况出现了:如果这些对象都占用相同大小的内存,你可以使用单独的一块内存,或缓存,来持有所有的这些对象。你需要的对象可以在这个缓存里以循环的方式分配和释放,所以它有时候被称为环缓存。这通常比堆内存分配更快。(译者注:这也被称为对象池。)
有时候你需要显式释放已分配的内存,所以它可以被重新分配而非依赖于垃圾回收机制。然后你必须谨慎机智地分配每一块内存,并且为它设计一种在合适的时候重新分配的方式。这种销毁的方式可能随着你创建的对象的不同而不同。你必须保证每个内存分配操作都与一个内存释放操作相匹配。(译者注:在C里面,no malloc no free,在C++里面,no new no delete)。这通常是很困难的,所以程序员通常会实现一种简单的方式或者垃圾回收机制,比如引用计数,来为它们做这件事情。
Copy link