• 清除时的困境:由谁负责清除?


    每个对象都要求资源才能“生存”,其中最令人注目的资源是内存。如果不再需要使用一个对象,就必须将 其清除,以便释放这些资源,以便其他对象使用。如果要解决的是非常简单的问题,如何清除对象这个问题 并不显得很突出:我们创建对象,在需要的时候调用它,然后将其清除或者“破坏”。但在另一方面,我们 平时遇到的问题往往要比这复杂得多。 举个例子来说,假设我们要设计一套系统,用它管理一个机场的空中交通(同样的模型也可能适于管理一个 仓库的货柜、或者一套影带出租系统、或者宠物店的宠物房。这初看似乎十分简单:构造一个集合用来容纳 飞机,然后创建一架新飞机,将其置入集合。对进入空中交通管制区的所有飞机都如此处理。至于清除,在 一架飞机离开这个区域的时候把它简单地删去即可。 但事情并没有这么简单,可能还需要另一套系统来记录与飞机有关的数据。当然,和控制器的主要功能不 同,这些数据的重要性可能一开始并不显露出来。例如,这条记录反映的可能是离开机场的所有小飞机的飞 行计划。所以我们得到了由小飞机组成的另一个集合。一旦创建了一个飞机对象,如果它是一架小飞机,那
    36
    么也必须把它置入这个集合。然后在系统空闲时期,需对这个集合中的对象进行一些后台处理。 问题现在显得更复杂了:如何才能知道什么时间删除对象呢?用完对象后,系统的其他某些部分可能仍然要 发挥作用。同样的问题也会在其他大量场合出现,而且在程序设计系统中(如C++),在用完一个对象之后 必须明确地将其删除,所以问题会变得异常复杂(注释⑥)。

    ⑥:注意这一点只对内存堆里创建的对象成立(用 new命令创建的)。但在另一方面,对这儿描述的问题以 及其他所有常见的编程问题来说,都要求对象在内存堆里创建。

    在Java 中,垃圾收集器在设计时已考虑到了内存的释放问题(尽管这并不包括清除一个对象涉及到的其他方 面)。垃圾收集器“知道”一个对象在什么时候不再使用,然后会自动释放那个对象占据的内存空间。采用 这种方式,另外加上所有对象都从单个根类Object 继承的事实,而且由于我们只能在内存堆中以一种方式创 建对象,所以Java 的编程要比 C++的编程简单得多。我们只需要作出少量的抉择,即可克服原先存在的大量 障碍。

    1. 垃圾收集器对效率及灵活性的影响 既然这是如此好的一种手段,为什么在C++里没有得到充分的发挥呢?我们当然要为这种编程的方便性付出 一定的代价,代价就是运行期的开销。正如早先提到的那样,在C++中,我们可在堆栈中创建对象。在这种 情况下,对象会得以自动清除(但不具有在运行期间随心所欲创建对象的灵活性)。在堆栈中创建对象是为 对象分配存储空间最有效的一种方式,也是释放那些空间最有效的一种方式。在内存堆(Heap)中创建对象 可能要付出昂贵得多的代价。如果总是从同一个基础类继承,并使所有函数调用都具有“同质多形”特征, 那么也不可避免地需要付出一定的代价。但垃圾收集器是一种特殊的问题,因为我们永远不能确定它什么时 候启动或者要花多长的时间。这意味着在 Java 程序执行期间,存在着一种不连贯的因素。所以在某些特殊的 场合,我们必须避免用它——比如在一个程序的执行必须保持稳定、连贯的时候(通常把它们叫作“实时程 序”,尽管并不是所有实时编程问题都要这方面的要求——注释⑦)。

    ⑦:根据本书一些技术性读者的反馈,有一个现成的实时 Java 系统(www.newmonics.com)确实能够保证垃 圾收集器的效能。

    C++语言的设计者曾经向C 程序员发出请求(而且做得非常成功),不要希望在可以使用 C 的任何地方,向语 言里加入可能对C++的速度或使用造成影响的任何特性。这个目的达到了,但代价就是C++的编程不可避免地 复杂起来。Java 比C++简单,但付出的代价是效率以及一定程度的灵活性。但对大多数程序设计问题来说, Java 无疑都应是我们的首选。

     1 package Com.TomTest;
     2 
     3 
     4 class Sum{
     5        int n;
     6         float f(){
     7       float sum=0;
     8            for(int i=1;i<=n;i++)
     9               sum=sum+i;
    10           return sum;  
    11         }
    12     }
    13     class Average extends Sum {
    14       int n;  
    15        float f(){
    16       float c;
    17           super.n=n;
    18           c=super.f();
    19           return c/n; 
    20        }
    21        float g(){
    22         float c;
    23          c=super.f();
    24           return c/2; 
    25        }
    26      }
    27     public class TomTest_30 {
    28         public static void main(String args[]) {
    29         Average aver=new Average();
    30            aver.n=100;
    31            float result_1=aver.f();
    32            float result_2=aver.g();
    33            System.out.println("result_1="+result_1);
    34            System.out.println("result_2="+result_2);
    35        }
    36     }
  • 相关阅读:
    java中计算两个时间差
    增强for循环用法
    SQLServer类型与Java类型转换问题解决
    有关SQL模糊查询
    js 弹出div窗口 可移动 可关闭 (转)
    登陆sqlserver及修改端口号 (转)
    C#判断IP地址是否合法函数-使用正则表达式-2个 (转)
    c#图像处理入门(-bitmap类和图像像素值获取方法) 转
    MongoDB C#驱动中Query几个方法 (转)
    微信公众帐号自定义菜单创建及事件响应开发教程 附源代码(转)
  • 原文地址:https://www.cnblogs.com/borter/p/9438518.html
Copyright © 2020-2023  润新知