- 写在前面的话
- 引言
- 第 1 章 对象入门
- 第 2 章 一切都是对象
- 第 3 章 控制程序流程
- 第 4 章 初始化和清除
- 第 5 章 隐藏实施过程
- 第 6 章 类再生
- 第 7 章 多形性
- 第 8 章 对象的容纳
- 第 9 章 违例差错控制
- 第 10 章 Java IO 系统
- 第 11 章 运行期类型鉴定
- 第 12 章 传递和返回对象
- 第 十三 章 创建窗口和程序片
- 第 14 章 多线程
- 第 15 章 网络编程
- 第 16 章 设计范式
- 第 17 章 项目
- 附录 A 使用非 JAVA 代码
- 附录 B 对比 C++和 Java
- 附录 C Java 编程规则
- 附录 D 性能
- 附录 E 关于垃圾收集的一些话
- 附录 F 推荐读物
1.7.4 清除时的困境:由谁负责清除?
每个对象都要求资源才能“生存”,其中最令人注目的资源是内存。如果不再需要使用一个对象,就必须将其清除,以便释放这些资源,以便其他对象使用。如果要解决的是非常简单的问题,如何清除对象这个问题并不显得很突出:我们创建对象,在需要的时候调用它,然后将其清除或者“破坏”。但在另一方面,我们平时遇到的问题往往要比这复杂得多。
举个例子来说,假设我们要设计一套系统,用它管理一个机场的空中交通(同样的模型也可能适于管理一个仓库的货柜、或者一套影带出租系统、或者宠物店的宠物房。这初看似乎十分简单:构造一个集合用来容纳飞机,然后创建一架新飞机,将其置入集合。对进入空中交通管制区的所有飞机都如此处理。至于清除,在一架飞机离开这个区域的时候把它简单地删去即可。
但事情并没有这么简单,可能还需要另一套系统来记录与飞机有关的数据。当然,和控制器的主要功能不同,这些数据的重要性可能一开始并不显露出来。例如,这条记录反映的可能是离开机场的所有小飞机的飞行计划。所以我们得到了由小飞机组成的另一个集合。一旦创建了一个飞机对象,如果它是一架小飞机,那么也必须把它置入这个集合。然后在系统空闲时期,需对这个集合中的对象进行一些后台处理。
问题现在显得更复杂了:如何才能知道什么时间删除对象呢?用完对象后,系统的其他某些部分可能仍然要发挥作用。同样的问题也会在其他大量场合出现,而且在程序设计系统中(如 C++),在用完一个对象之后必须明确地将其删除,所以问题会变得异常复杂(注释⑥)。
⑥:注意这一点只对内存堆里创建的对象成立(用 new 命令创建的)。但在另一方面,对这儿描述的问题以及其他所有常见的编程问题来说,都要求对象在内存堆里创建。
在 Java 中,垃圾收集器在设计时已考虑到了内存的释放问题(尽管这并不包括清除一个对象涉及到的其他方面)。垃圾收集器“知道”一个对象在什么时候不再使用,然后会自动释放那个对象占据的内存空间。采用这种方式,另外加上所有对象都从单个根类 Object 继承的事实,而且由于我们只能在内存堆中以一种方式创建对象,所以 Java 的编程要比 C++的编程简单得多。我们只需要作出少量的抉择,即可克服原先存在的大量障碍。
1. 垃圾收集器对效率及灵活性的影响
既然这是如此好的一种手段,为什么在 C++里没有得到充分的发挥呢?我们当然要为这种编程的方便性付出一定的代价,代价就是运行期的开销。正如早先提到的那样,在 C++中,我们可在堆栈中创建对象。在这种情况下,对象会得以自动清除(但不具有在运行期间随心所欲创建对象的灵活性)。在堆栈中创建对象是为对象分配存储空间最有效的一种方式,也是释放那些空间最有效的一种方式。在内存堆(Heap)中创建对象可能要付出昂贵得多的代价。如果总是从同一个基础类继承,并使所有函数调用都具有“同质多形”特征,那么也不可避免地需要付出一定的代价。但垃圾收集器是一种特殊的问题,因为我们永远不能确定它什么时候启动或者要花多长的时间。这意味着在 Java 程序执行期间,存在着一种不连贯的因素。所以在某些特殊的场合,我们必须避免用它——比如在一个程序的执行必须保持稳定、连贯的时候(通常把它们叫作“实时程序”,尽管并不是所有实时编程问题都要这方面的要求——注释⑦)。
⑦:根据本书一些技术性读者的反馈,有一个现成的实时 Java 系统(www.newmonics.com)确实能够保证垃圾收集器的效能。
C++语言的设计者曾经向 C 程序员发出请求(而且做得非常成功),不要希望在可以使用 C 的任何地方,向语言里加入可能对 C++的速度或使用造成影响的任何特性。这个目的达到了,但代价就是 C++的编程不可避免地复杂起来。Java 比 C++简单,但付出的代价是效率以及一定程度的灵活性。但对大多数程序设计问题来说,Java 无疑都应是我们的首选。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论