周桂盛-外文翻译

上传人:豆浆 文档编号:804567 上传时间:2017-05-15 格式:DOC 页数:11 大小:68.50KB
返回 下载 相关 举报
周桂盛-外文翻译_第1页
第1页 / 共11页
周桂盛-外文翻译_第2页
第2页 / 共11页
周桂盛-外文翻译_第3页
第3页 / 共11页
周桂盛-外文翻译_第4页
第4页 / 共11页
周桂盛-外文翻译_第5页
第5页 / 共11页
点击查看更多>>
资源描述

《周桂盛-外文翻译》由会员分享,可在线阅读,更多相关《周桂盛-外文翻译(11页珍藏版)》请在金锄头文库上搜索。

1、本 科 毕 业 设 计 (论 文 )外文翻译(附外文原文)学 院: 信息科学与工程学院 课 题 名 称 :基于 SSH2 框架的网上书店 的设计与实现 专业(方向):计算机科学与技术(应用) 班 级: 计本 08-1 学 生: 周桂盛 指 导 教 师 : 叶 苗 日 期: 2012 年 4 月 28 日 1Java 理论和实践: 用软引用阻止内存泄漏垃圾收集可以使 Java 程序不会出现内存泄漏,至少对于比较狭窄的 “内存泄漏” 定义来说如此,但是这并不意味着我们可以完全忽略 Java 程序中的对象生存期(lifetime)问题。当我们没有对对象生命周期(lifecycle)引起足够的重视或者

2、破坏了管理对象生命周期的标准机制时,Java 程序中通常就会出现内存泄漏。例如,上一次 我们看到了,不能划分对象的生命周期会导致,在试图将元数据关联到瞬时对象时出现意外的对象保持。还有一些其他的情况可以类似地忽略或破坏对象生命周期管理,并导致内存泄漏。对象游离一种形式的内存泄漏有时候叫做对象游离(object loitering) ,是通过清单 1 中的 LeakyChecksum 类来说明的,清单 1 中有一个 getFileChecksum() 方法用于计算文件内容的校验和。getFileChecksum() 方法将文件内容读取到缓冲区中以计算校验和。一种更加直观的实现简单地将缓冲区作为

3、getFileChecksum() 中的本地变量分配,但是该版本比那样的版本更加 “聪明”,不是将缓冲区缓存在实例字段中以减少内存 churn。该 “优化”通常不带来预期的好处;对象分配比很多人期望的更便宜。 (还要注意,将缓冲区从本地变量提升到实例变量,使得类若不带有附加的同步,就不再是线程安全的了。直观的实现不需要将 getFileChecksum() 声明为 synchronized,并且会在同时调用时提供更好的可伸缩性。 ) 清单 1. 展示 “对象游离” 的类/ BAD CODE - DO NOT EMULATEpublic class LeakyChecksum private b

4、yte byteArray;public synchronized int getFileChecksum(String fileName) int len = getFileSize(fileName);if (byteArray = null | byteArray.length bufferRef;public synchronized int getFileChecksum(String fileName) int len = getFileSize(fileName);byte byteArray = bufferRef.get();if (byteArray = null | by

5、teArray.length 或 SoftReference 管理。后一种选项通常更好一些,因为它给垃圾收集器带来的工作更少,并且允许在特别需要内存时以较少的工作回收整个缓存。弱引用有时会错误地用于取代软引用,用于构建缓存,但是这会导致差的缓存性能。在实践中,弱引用将在对象变得弱可及之后被很快地清除掉 通常是在缓存的对象再次用到之前 因为小的垃圾收集运行得很频繁。 对于在性能上非常依赖高速缓存的应用程序来说,软引用是一个不管用的手段,它确实不能取代能够提供灵活终止期、复制和事务型高速缓存的复杂的高速缓存框架。但是作为一种 “廉价(cheap and dirty) ” 的高速缓存机制,它对于降低

6、价格是很有吸引力的。正如弱引用一样,软引用也可创建为具有一个相关的引用队列,引用在被垃圾收集器清除时进入队列。引用队列对于软引用来说,没有对弱引用那么有用,但是它们可以用于发出管理警报,说明应用程序开始缺少内存。 垃圾收集器如何处理 References弱引用和软引用都扩展了抽象的 Reference 类(虚引用(phantom references)也一样,这将在以后的文章中介绍) 。引用对象被垃圾收集器特殊地看待。垃圾收集器在跟踪堆期间遇到一个 Reference 时,不会标记或跟踪该引用对象,而是在已知活跃的 Reference 对象的队列上放置一个 Reference。在跟踪之后,垃圾

7、收集器就识别软可及的对象 这些对象上除了软引用外,没有任何强引用。垃圾收集器然后根据当前收集所回收的内存总量和其他策略考虑因素,判断软引用此时是否需要被清除。将被清除的软引用如果具有相应的引用队列,就会进入队列。其余的软可及对象(没有清除的对象)然后被看作一个根集(root set) ,堆跟踪继续使用这些新的根,以便通过活跃的软引用而可及的对象能够被标记。 处理软引用之后,弱可及对象的集合被识别 这样的对象上不存在强引用或软引用。这些对象被清除和加入队列。所有 Reference 类型在加入队列之前被清除,所以处理事后检查(post-mortem)清除的线程永远不会具有 referent 对象

8、的访问权,而只具有 Reference 对象的访问权。因此,当 References 与引用队列一起使用时,通常需要细分适当的引用类型,并将它直接用于您的设计中(与 WeakHashMap 一样,它的 Map.Entry 扩展了 WeakReference)或者存储对需要清除的实体的引用。引用处理的性能成本4引用对象给垃圾收集过程带来了一些附加的成本。每一次垃圾收集,都必须构造活跃 Reference 对象的一个列表,而且每个引用都必须做适当的处理,这给每次收集添加了一些每个 Reference 的开销,而不管该 referent 此时是否被收集。Reference 对象本身服从于垃圾收集,并

9、且可在 referent 之前被收集,在这样的情况下,它们没有加入队列。 基于数组的集合当数组用于实现诸如堆栈或环形缓冲区之类的数据结构时,会出现另一种形式的对象游离。清单 3 中的 LeakyStack 类展示了用数组实现的堆栈的实现。在 pop() 方法中,在顶部指针递减之后,elements 仍然会保留对将弹出堆栈的对象的引用。这意味着,该对象的引用对程序来说仍然可及(即使程序实际上不会再使用该引用) ,这会阻止该对象被垃圾收集,直到该位置被未来的 push() 重用。 清单 3. 基于数组的集合中的对象游离 public class LeakyStack private Object

10、elements = new ObjectMAX_ELEMENTS;private int size = 0;public void push(Object o) elementssize+ = o; public Object pop() if (size = 0)throw new EmptyStackException();else Object result = elements-size;/ elementssize+1 = null;return result; 修复这种情况下的对象游离的方法是,当对象从堆栈弹出之后,就消除它的引用,如清单 3 中注释掉的行所示。但是这种情况 由类

11、管理其自己的内存 是一种非常少见的情况,即显式地消除不再需要的对象是一个好主意。大部分时候,认为不应该使用的强行消除引用根本不会带来性能或内存使用方面的收益,通常是导致更差的性能或者 NullPointerException。该算法的一个链接实现不会存在这个问题。在链接实现中,链接节点(以及所存储的对象的引用)的生命期将被自动与对象存储在集合中的期间绑定在一起。弱引用可用于解决这个问题 维护弱引用而不是强引用的一个数组 但是在实际中,LeakyStack 管理它自己的内存,因此负责确保对不再需要的对象的引用被清除。使用数组来实现堆栈或缓冲区是一种优化,可以减少分配,但是会给实现者带来更大的负担

12、,需要仔细地管理存储在数组中的引用的生命期。 结束语5与弱引用一样,软引用通过利用垃圾收集器在作出缓存回收决策方面的帮助,有助于防止应用程序出现对象游离。只有当应用程序可以忍受大量软引用的对象时,软引用才适合使用。 关于作者 Brian Goetz 作为一位专业软件开发人员将近超过 18 年。他是位于加州Los Altos 的提供软件开发和咨询的 Quiotix 公司的首席顾问,他为多个 JCP专家组服务。布莱恩的书, Java Concurrency In Practice ,将在 2005 年年底,由 Addison-Wesley 出版。Java theory and practice:

13、Plugging memory leaks with soft referencesGarbage collection might make Java programs immune to memory leaks, at least for a sufficiently narrow definition of memory leak, but that doesnt mean we can totally ignore the issue of object lifetime in Java programs. Memory leaks in Java programs usually

14、arise when we pay insufficient attention to object lifecycle or subvert the standard mechanisms for managing object lifecycle. For example, last time we saw how failing to demarcate an objects lifecycle could cause unintentional object retention when trying to associate metadata with transient objec

15、ts. There are other idioms that can similarly ignore or subvert object lifecycle management and can also lead to memory leaks. Object loitering6A form of memory leak, sometimes called object loitering, is illustrated by the LeakyChecksum class in Listing 1, which provides a getFileChecksum() method

16、to calculate the checksum of a files contents. The getFileChecksum() method reads the contents of the file into a buffer to compute the checksum. A more straightforward implementation would simply allocate the buffer as a local variable within getFileChecksum(), but this version is more clever than tha

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号