Java理论与实践 - 它是谁的对象?[Java编程]
本文“Java理论与实践 - 它是谁的对象?[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
在没有垃圾汇集的语言中,比方C++,必须分外关注内存管理.关于每个动态 对象,必必要末实现引用计数以模拟 垃圾汇集效果,要末管理每个对象的“所 有权”――肯定哪个类负责删除一个对象.普通,对这种全部权的保护并没有什 么成文的法则,而是按照约定(普通是不成文的)举行保护.固然垃圾汇集意味 着Java开辟者没必要太多地耽忧内存 泄露,有时我们仍旧需求耽忧对象全部权, 以避免数据争用(data races)和不必要的副作用.在这篇文章中,Brian Goetz 指出了一些这样的情形,即Java开辟者必须注意对象全部权.
假如您是在1997年之前开始学习编程,那么大概您学习的第一种编程语言没 有供应透明的垃圾汇集.每一个new 操作必须有呼应的delete操作 ,不然您的 程序就会泄露内存,终究内存分配器(memory allocator )就会出弊端,而您 的程序就会崩溃.每当操纵 new 分配一个对象时,您就得问自己,谁将删除该 对象?什么时刻删除?
别名, 也叫做 ...
内存管理复杂性的主要缘由是别名利用:同一块内存或对象具有 多个指针或 引用.别名在任什么时刻候城市很自然地呈现.比方,在清单 1 中,在 makeSomething 的第一行成立的 Something 对象至少有四个引用:
something 引用.
调集 c1 中至少有一个引用.
当 something 被作为参数传送给 registerSomething 时,会成立暂时 aSomething 引用.
调集 c2 中至少有一个引用.
清单 1. 典型代码中的别名
Collection c1, c2;
public void makeSomething {
Something something = new Something();
c1.add(something);
registerSomething(something);
}
private void registerSomething(Something aSomething) {
c2.add(aSomething);
}
在非垃圾汇集语言中需求避免两个主要的内存管理危险:内存泄露和悬空指 针.为了避免内存泄露,必须确保每个分配了内存的对象终究城市被删除.为了 避免悬空指针(一种危险的情形,即一块内存已经被释放了,而一个指针还在引 用它),必须在最后的引用释放之后才删除对象.为满意这两条约束,采取一定 的战略是很重要的.
为内存管理而管理对象全部权
除了垃圾汇集之外,普通还有其他两种办法用于处理别名问题: 引用计数和 全部权管理.引用计数(reference counting)是对一个给定的对象当前有多少 指向它的引用保存有一个计数,然后当最后一个引用被释放时自动删除该对象. 在 C和20世纪90年代中期之前的大都 C++ 版本中,这是不大概自动完成的.标 准模板库(Standard Template Library,STL)答应成立“机灵”指针,而不能 自动实现引用计数(要查看一些例子,请拜见开放源代码 Boost 库中的 shared_ptr 类,大概拜见STL中的越发简单的 auto_ptr 类).
全部权管理(ownership management) 是这样一个历程,该历程指明一个指 针是“拥有”指针("owning" pointer),而 全部其他别名只是暂时的二类副 本( temporary second-class copies),并且只在所拥有的指针被释放时才删 除对象.在有些情形下,全部权可以从一个指针“转移”到另一个指针,比方一 个这样的办法,它以一个缓冲区作为参数,该办法用于向一个套接字写数据,并 且在写操作完成时删除这个缓冲区.这样的办法普通叫做接纳器 (sinks).在 这个例子中,缓冲区的全部权已经被有效地转移,因而举行调用的代码必须假定 在被调用办法返回时缓冲区已经被删除.(通过确保全部的别名指针都具有与调 用仓库(比方办法参数或部分变量)一致的作用域(scope ),可以进一步简化 全部权管理,假如引用将由非仓库作用域的变量保存,则通过复制对象来举行简 化.)
那么,怎么着?
此时,您大概正烦闷,为什么我还要谈论内存管理、别名和对象全部权.毕 竟,垃圾汇集是 Java语言的核心特点之一,而内存管理是已经过期的一件麻烦 事.就让垃圾汇集器来处理这件事吧,这恰是它的工作.那些从内存管理的麻烦 中摆脱出来的人不肯意再回到过去,而那些从未处理过内存管理的人则根本无法 想象在过去倒运的日子里――比方1996年――程序员的编程是多么可怕.
防备悬空别名
那么这意味着我们可以与对象全部权的概念说再见了吗?可以说是,也可以 说不是.大大都情形下,垃圾汇集确切消除了显式资源存储单元分配(explicit resource deallocation)的必要(在今后的专栏中我将谈论一些例外).但是 ,有一个区域中,全部权管理仍旧是Java 程序中的一个问题,而这就是悬空别 名(dangling aliases)问题.Java 开辟者普通依靠于这样一个隐含的假定, 即假定由对象全部权来肯定哪些引用应当被看做是只读的 (在C++中就是一个 const 指针),哪些引用可以用来改正被引用的对象的状况.当两个类都(错误 地)认为自己保存有对给定对象的惟一可写的引用时,就会呈现悬空指针.发生 这种情形时,假如对象的状况被不测地更改,这两个类中的一个或二者将会产生 混合.
以上是“Java理论与实践 - 它是谁的对象?[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |