精华内容
下载资源
问答
  • 内存模型是随着越来越丰富复杂的对象生命周期要求的发展发展起来。最初内存模型完全是线性,静态,一个程序运行时所有需要的对象都是在运行前完全准备好了,运行完了时释放掉。典型代表就是Fortran...
    内存模型是随着越来越丰富和复杂的对象生命周期要求的发展而发展起来的。 

    最初的内存模型完全是线性的,静态的,一个程序运行时所有需要的对象都是在运行前完全准备好了的,运行完了时释放掉。典型的代表就是Fortran语言。这种语言的运行性能非常高(当然了,没有任何别的消耗嘛),但是表达能力受到限制(毕竟,要求静态的确定一切对象和内存的绑定关系)。最明显的一个限制就是没办法支持递归。这种内存模型支持的对象的生命周期跟应用程序的生命周期完全一致。同生共死,天下大同。 

    Alogal的出现引入了一个强大的概念: lexical scope,内存模型也相应的出现了细分概念:栈。栈就是那种先进后出的容器,它完美的切合了lexical scope。同时,栈上的对象的生命周期也很清晰,进栈是出生,出栈时死亡。栈这个概念是如此的清晰、容易理解,而且如此的强大,导致现代各种语言的内存模型中,栈都占有非常显著的地位。栈自然地解决了递归问题。栈上对象的生命周期的管理完全可以自动化而高效的完成。但是,栈仍然不足以满足某些对象生命周期的要求。 

    我先说说这是那种样子的生命周期。简单的说,栈对于共享的对象的生命周期无能为力。也就是说,某个对象,在多个平级的或者嵌套的scope之间共享,而栈却没办法解决。非得用栈来满足这种需求的话,会导致大量的memcpy,导致性能的低下。而且还是模拟的解决这个问题。其实,对于参数和返回值,基于栈架构的内存模型和对象就是采用复制和反向复制的方式来完成的。 

    面对这个挑战(共享对象生命周期问题),第一个反应就是避免共享,其实就是我前面说的完全副本的方式。这种方式在一定程度上有效,不过,对于大对象是非常不划算的。 

    C 和Pascal语言来了,这类语言提供了另一个概念叫做堆(其实,堆这个概念并不是它们最先引入的,但是是由它们发扬光大的)。从此内存模型分裂为两个界限明显的类型:栈和堆。堆就是那种随机进随机出的对象的栖息之地。也就是说,这种对象的生命周期不再可以向栈对象那样自动高效的管理了。有了这样的基础设施,共享对象就变得简单了。创建一个堆对象,然后A使用之,只要不销毁,B就可以使用之,这样,该对象就可以由A和B共享了。当然,牵扯到共享,必然会涉及到同步和互斥的问题。也就是A和B究竟怎样访问该对象的问题。一般来说,采取的策略是是把并发访问串行化的技术。由此导出很多互斥的技术。我们就不在这上面纠缠了。我们关注的是对象本身的生命周期,也就是说。这个可以共享的对象的生、死问题。由谁负责生(创建)似乎大家都没有什么抱怨的,由第一个要用该对象的负责,这也不会导致麻烦。原因是:如果你不负责生,那么该对象就不存在,你也就没办法使用了。:)由谁负责死(销毁)呢。这个看起来也很简单:最后一个用完了就销毁。而事实上也确实就这么简单。但是这儿有一点麻烦。跟创建不一样,创建不会被忘记,而销毁会。忘记销毁对象对自己没有伤害,所以,就选择忘记吧。:)这不是拉屎不擦屁股的问题。这个不难受。 

    这样说吧。现代的语言按照由谁负责堆对象的销毁问题大致可以分成两大类,一类叫做有垃圾回收的,一类没有。有垃圾回收的那一类是由运行环境(运行时)负责销毁共享对象,没有垃圾回收的那一类由程序自己负责销毁共享对象。对程序员来说,当然有垃圾回收的语言跟友好了。但问题是垃圾回收需要首先搞定哪一些共享对象不再需要了。这是一个比较困难的问题。而对于没有垃圾回收的那种语言来说,程序自己逻辑上应该很清楚哪一些对象不再需要了,可以销毁了。 

    一般情况下,我们把那些由运行时负责销毁共享对象的那些堆叫做托管堆,负责销毁共享对象的运行时的一部分叫做垃圾回收器(GC),也就是说,托管堆就使那种委托给GC管理的堆。 
    相应的,没有委托给GC管理的堆就是普通的堆了。普通堆有应用程序自己负责销毁共享对象。 

    上面的描述还没有提到的一个问题是:对象究竟在什么时候销毁?由于一个对象不立即销毁一般不会导致什么重大的问题,所以销毁的时机相对来说可以很灵活。当然,肯定是在最后一个使用了以后。但是以后是多久呢?是立即销毁?还是延迟一段时间?如果是延迟,那么究竟延迟多长时间?还是更进一步的说延迟不定长的时间? 

    由于一般情况下,我们认为批量销毁比一个一个销毁要快一些,所以一个指导性的方案就是等到垃圾(生命周期应该已经结束了的共享对象)积累到一定的量以后(只要不影响程序的正常运行)批量销毁。这一般会导致销毁的不定长延迟。 

    上面说了:“由于一个对象不立即销毁一般不会导致什么重大的问题,所以销毁的时机相对来说可以很灵活。”。注意这个句子里面的“一般”这个字眼,这也就是说:在特殊情况下,不立即销毁会导致重大问题。那种情况是特殊情况呢?就是那种销毁对象的动作还带有别的副作用,而这个副作用会影响以后程序的运作行为的情况。这种情况在使用C++的RAII的时候是基本情况。 

    现在粗略的说说垃圾回收的基本方法。 

    我们把托管堆中的对象以及对象的互相引用关系看作是一个“图”(数学上定点和边的集合),应用程序的栈上有一些引用引用到这个图的某些顶点。从GC的角度来看,应用程序的作用就是不断地改变图的连通性,故此把应用程序叫做Mutator。GC就是通过查看图的连通性把那些孤立的顶点(就是那种生命周期结束的共享对象)回收的。 

    那么,我们怎么知道图的连通性的呢? 

    1、可以通过从根集跟踪。所谓根集,就是应用程序栈上的引用集合。我们知道,这种跟踪肯定可以搞定图的连通性,但是,这要求我们能够区分什么是引用,而什么不是。 
    2、每次应用程序修改图的连通性的时候,记录下来。这样GC就可以直接销毁那些孤立的顶点了。 
    第一种方式是最常用的方式,或者甚至可以这样说,第二种方式根本没人用。 

    不过,第二种方式的某种变形方式用的人却很多。那就是RefCount。第二种方式把集中存放的连通图信息分散的放置到各个共享对象身上,让他们记住自己被多少个别的对象引用就行了。这样当它发觉自己被0个对象引用的时候,就自裁。 

    这个方式看起来非常好,也非常干净,但是有两个缺点。一是性能。每一次引用一个对象,都需要增加这个引用计数,放弃引用的时候得减少之。影响了性能。另一个是对于环形图的无能为力。

    转载于:https://www.cnblogs.com/lxfgood/archive/2011/03/16/1985595.html

    展开全文
  • 内存模型是随着越来越丰富复杂的对象生命周期要求的发展发展起来。 最初内存模型完全是线性,静态,一个程序运行时所有需要的对象都是在运行前完全准备好了,运行完了时释放掉。典型代表就是...
    内存模型是随着越来越丰富和复杂的对象生命周期要求的发展而发展起来的。

    最初的内存模型完全是线性的,静态的,一个程序运行时所有需要的对象都是在运行前完全准备好了的,运行完了时释放掉。典型的代表就是Fortran语言。这种语言的运行性能非常高(当然了,没有任何别的消耗嘛),但是表达能力受到限制(毕竟,要求静态的确定一切对象和内存的绑定关系)。最明显的一个限制就是没办法支持递归。这种内存模型支持的对象的生命周期跟应用程序的生命周期完全一致。同生共死,天下大同。

    Alogal的出现引入了一个强大的概念: lexical scope,内存模型也相应的出现了细分概念:栈。栈就是那种先进后出的容器,它完美的切合了lexical scope。同时,栈上的对象的生命周期也很清晰,进栈是出生,出栈时死亡。栈这个概念是如此的清晰、容易理解,而且如此的强大,导致现代各种语言的内存模型中,栈都占有非常显著的地位。栈自然地解决了递归问题。栈上对象的生命周期的管理完全可以自动化而高效的完成。但是,栈仍然不足以满足某些对象生命周期的要求。

    我先说说这是那种样子的生命周期。简单的说,栈对于共享的对象的生命周期无能为力。也就是说,某个对象,在多个平级的或者嵌套的scope之间共享,而栈却没办法解决。非得用栈来满足这种需求的话,会导致大量的memcpy,导致性能的低下。而且还是模拟的解决这个问题。其实,对于参数和返回值,基于栈架构的内存模型和对象就是采用复制和反向复制的方式来完成的。

    面对这个挑战(共享对象生命周期问题),第一个反应就是避免共享,其实就是我前面说的完全副本的方式。这种方式在一定程度上有效,不过,对于大对象是非常不划算的。

    C 和Pascal语言来了,这类语言提供了另一个概念叫做堆(其实,堆这个概念并不是它们最先引入的,但是是由它们发扬光大的)。从此内存模型分裂为两个界限明显的类型:栈和堆。堆就是那种随机进随机出的对象的栖息之地。也就是说,这种对象的生命周期不再可以向栈对象那样自动高效的管理了。有了这样的基础设施,共享对象就变得简单了。创建一个堆对象,然后A使用之,只要不销毁,B就可以使用之,这样,该对象就可以由A和B共享了。当然,牵扯到共享,必然会涉及到同步和互斥的问题。也就是A和B究竟怎样访问该对象的问题。一般来说,采取的策略是是把并发访问串行化的技术。由此导出很多互斥的技术。我们就不在这上面纠缠了。我们关注的是对象本身的生命周期,也就是说。这个可以共享的对象的生、死问题。由谁负责生(创建)似乎大家都没有什么抱怨的,由第一个要用该对象的负责,这也不会导致麻烦。原因是:如果你不负责生,那么该对象就不存在,你也就没办法使用了。:)由谁负责死(销毁)呢。这个看起来也很简单:最后一个用完了就销毁。而事实上也确实就这么简单。但是这儿有一点麻烦。跟创建不一样,创建不会被忘记,而销毁会。忘记销毁对象对自己没有伤害,所以,就选择忘记吧。:)这不是拉屎不擦屁股的问题。这个不难受。

    这样说吧。现代的语言按照由谁负责堆对象的销毁问题大致可以分成两大类,一类叫做有垃圾回收的,一类没有。有垃圾回收的那一类是由运行环境(运行时)负责销毁共享对象,没有垃圾回收的那一类由程序自己负责销毁共享对象。对程序员来说,当然有垃圾回收的语言跟友好了。但问题是垃圾回收需要首先搞定哪一些共享对象不再需要了。这是一个比较困难的问题。而对于没有垃圾回收的那种语言来说,程序自己逻辑上应该很清楚哪一些对象不再需要了,可以销毁了。

    一般情况下,我们把那些由运行时负责销毁共享对象的那些堆叫做托管堆,负责销毁共享对象的运行时的一部分叫做垃圾回收器(GC),也就是说,托管堆就使那种委托给GC管理的堆。
    相应的,没有委托给GC管理的堆就是普通的堆了。普通堆有应用程序自己负责销毁共享对象。

    上面的描述还没有提到的一个问题是:对象究竟在什么时候销毁?由于一个对象不立即销毁一般不会导致什么重大的问题,所以销毁的时机相对来说可以很灵活。当然,肯定是在最后一个使用了以后。但是以后是多久呢?是立即销毁?还是延迟一段时间?如果是延迟,那么究竟延迟多长时间?还是更进一步的说延迟不定长的时间?

    由于一般情况下,我们认为批量销毁比一个一个销毁要快一些,所以一个指导性的方案就是等到垃圾(生命周期应该已经结束了的共享对象)积累到一定的量以后(只要不影响程序的正常运行)批量销毁。这一般会导致销毁的不定长延迟。

    上面说了:“由于一个对象不立即销毁一般不会导致什么重大的问题,所以销毁的时机相对来说可以很灵活。”。注意这个句子里面的“一般”这个字眼,这也就是说:在特殊情况下,不立即销毁会导致重大问题。那种情况是特殊情况呢?就是那种销毁对象的动作还带有别的副作用,而这个副作用会影响以后程序的运作行为的情况。这种情况在使用C++的RAII的时候是基本情况。

    现在错略的说说垃圾回收的基本方法。

    我们把托管堆中的对象以及对象的互相引用关系看作是一个“图”(数学上定点和边的集合),应用程序的栈上有一些引用引用到这个图的某些顶点。从GC的角度来看,应用程序的作用就是不断地改变图的连通性,故此把应用程序叫做Mutator。GC就是通过查看图的连通性把那些孤立的顶点(就是那种生命周期结束的共享对象)回收的。

    那么,我们怎么知道图的连通性的呢?

    1、可以通过从根集跟踪。所谓根集,就是应用程序栈上的引用集合。我们知道,这种跟踪肯定可以搞定图的连通性,但是,这要求我们能够区分什么是引用,而什么不是。
    2、每次应用程序修改图的连通性的时候,记录下来。这样GC就可以直接销毁那些孤立的顶点了。
    第一种方式是最常用的方式,或者甚至可以这样说,第二种方式根本没人用。

    不过,第二种方式的某种变形方式用的人却很多。那就是RefCount。第二种方式把集中存放的连通图信息分散的放置到各个共享对象身上,让他们记住自己被多少个别的对象引用就行了。这样当它发觉自己被0个对象引用的时候,就自裁。

    这个方式看起来非常好,也非常干净,但是有两个缺点。一是性能。每一次引用一个对象,都需要增加这个引用计数,放弃引用的时候得减少之。影响了性能。另一个是对于环形图的无能为力。
    展开全文
  • 电信运营商定位将是平台网络提供者,采取有效运营机制鼓励和发展社会IT公司、网站网页制作公司作为代理发展网交会各项业务。 电信运营商经济收益来自直接收益潜在收益两部分。直接收益:一是参展企业...
  • 2.6 面向对象的程序设计 33 2.6.1 具体类型的问题 33 2.6.2 类层次结构 34 2.7 通用型程序设计 36 2.7.1 容器 36 2.7.2 通用型算法 37 2.8 附言 38 2.9 忠告 39 第3章 标准库概览 40 3.1 引言 40 3.2 ...
  • C++程序设计语言(特别版)--源代码

    热门讨论 2012-04-23 07:33:51
    2.6 面向对象的程序设计 33 2.6.1 具体类型的问题 33 2.6.2 类层次结构 34 2.7 通用型程序设计 36 2.7.1 容器 36 2.7.2 通用型算法 37 2.8 附言 38 2.9 忠告 39 第3章 标准库概览 40 3.1 引言 40 3.2 ...
  • 2.6 面向对象的程序设计 33 2.6.1 具体类型的问题 33 2.6.2 类层次结构 34 2.7 通用型程序设计 36 2.7.1 容器 36 2.7.2 通用型算法 37 2.8 附言 38 2.9 忠告 39 第3章 标准库概览 40 3.1 引言 40 3.2 ...
  • Java产生与流行是当今Internet发展的客观要求,Java是一门各方面性能都很好编程语言,它基本特点是简单、面向对象、分布式、解释、健壮、安全、结构中立、可移植、性能很优异、多线程、动态,...
  • 还可以享受灵活桌面,自己制定快捷键,直接进入各个子程序和模块。 更便利模型导入和导出 ease 4.0中建筑模型导入相对于ease3.0更为简单。局部模型的对象定义使房间建模更简化。这个功能相当于autocad中...
  • 结构化程序设计由于采用了模块分解与功能抽象,自顶向下、分而治之的方法,从而有效地将一个较复杂的程序系统设计任务分解成许多易于控制处理的子任务,便于开发维护。 虽然结构化程序设计方法具有很多的优点,...
  • 随着“后 PC 时代”来临,Android(安卓)系统正在成为全球最受欢迎应用平台之一,每天 70 万部 Android 手机激活量直接预示着,其未来的发展格局无疑将成为相关产业竞相追逐的对象和焦点。 Android 平台上...
  •  GC是垃圾收集意思(Gabage Collection),内存处理是编程人员容易出现问题地方,忘记或者错误内存回收会导致程序或系统不稳定甚至崩溃,Java提供GC功能可以自动监测对象是否超过作用域从而达到自动回收...
  • 这种不能储备,需要量又是瞬息万变行业,就要求对供给需求要有精确掌握,以便及时进行调整控制,才不至于出现象美国加州那样长期电力危机。 中国电力行业还有它自己特点。中国电力行业垄断说到底是非...
  • 用java语言来设计一个游戏,不同于现在大型网络游戏手机游戏,也不同于其他小型单机控制程序,它对游戏编写者对java语言特点认知、语法运用、工作模式、面向对象的理解把握都提出了更高的要求,特别是在...
  • 它不但具有程序框架自动生成、灵活方便的类管理、代码编写界面设计集成交互操作、可开发多种程序等优点,而且通过简单的设置就可使其生成的程序框架支持数据库接口、OLE2,WinSock网络、3D控制界面。它以拥有...
  • 它吸收了C++、Visual Basic、Delphi、Java等语言的优点,体现了当今最新的程序设计技术的功能精华。C#继承了C语言的语法风格,同时又继承了C++的面向对象特征。不同的是,C#的对象模型已经面向Internet进行了重新...
  • 图像处理日益成为一门引人注目、前景远大学科,而MATLAB语言以强大科学运算、灵活程序设计流程、高质量图形可视化与界面设计、与其他程序和语言便捷接口功能,成为当今国际上科学界最具影响力、最有活力...
  • 它不但具有程序框架自动生成、灵活方便的类管理、代码编写界面设计集成交互操作、可开发多种程序等优点,而且通过简单的设置就可使其生成的程序框架支持数据库接口、OLE2,WinSock网络、3D控制界面。它以拥有...
  • 针对需求不确定的应用,可以使用渐进迭代类的开发模型。还可以采用快速应用程序开发(RAD)协同应用程序开发(JAD)技术,由软件开发者用户代表共同参与开发软件规范。RADJAD的基本思路是开发者用户共同设计...
  • 在编写游戏程序的过程中将程序设计知识点有机地分散在游戏中,是设计语言众多的对象、属性、方法以及程序开发工具各种设置操作都变得具体、形象、直观,通俗易懂,深入浅出。我想我们能够通过游戏程序的设计学会...
  • Java产生与流行是当今Internet发展的客观要求,Java是一门各方面性能都很好编程语言,它基本特点是简单、面向对象、分布式、解释、健壮、安全、结构中立、可移植、性能很优异、多线程、动态,...
  • 本系统使用的开发语言是Java语言,Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,Java 技术具有卓越的通用性、高效性、平台移植性安全性,广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机...
  • 主要工作是发展 Web 规范,这些规范描述了 Web 通信协议(比如 HTML XHTML)其他构建模块。 NativeApp 使用传统原生态Android SDK来实现应用 WebApp 基于浏览器来实现一种应用 HybridApp 一种可以...
  • 本书主要内容 ·如何确定满足用户需求数据库要求 ·使用各种建模技术构建数据模型方法,包括实体关系模型、用户界面模型语义对象模型 ·了解不同类型数据库技巧,包括关系数据库、FlatFiles、电子表格、...
  • 我使用BORLAND公司Delphi开发工具,利用其提供各种面向对象的开发工具,尤其是数据窗口这一能方便而简洁操纵数据库智能化对象,首先在短时间内建立系统应用原型,然后,对初始原型系统进行需求迭代,不断修正改进,...
  • 面向对象的开发方法包括面向对象的分析、面向对象的设计面向对象的程序设计。( √) 7. 软件危机的主要表现是软件的需求量迅速增加,软件价格上升。(×) 8. 软件工具的作用是为了延长软件产品的寿命。(×) 9. ...
  • 不幸是,虽然关系型数据库历经了约30年的发展,有成熟理论大量实践基础,但是,大多数设计、开发人员在设计数据库结构时仍然是“跟着感觉走”,根据业务需要编程方便,把字段这张表放几个那张表放几个...
  • 不幸是,虽然关系型数据库历经了约30年的发展,有成熟理论大量实践基础,但是,大多数设计、开发人员在设计数据库结构时仍然是“跟着感觉走”,根据业务需要编程方便,把字段这张表放几个那张表放几个...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 130
精华内容 52
关键字:

发展对象确定的程序和要求