java 板


LINE

原文是从下面这个网址取得 http://big5.ccidnet.com:89/gate/big5/java.ccidnet.com/ art/297/20060809/790019_1.html 然後修改错字、删赘字、替换台湾惯用语与标点符号、重新排版而成。 大部分修改都有附上原文,以防失去替换有误。 少数赘字 & 标点符号更换则没有。 这篇文章好像已经没啥版权问题?我不清楚 不过... 万一我因此被抓去关,大家记得要来看我... [茶] ====================================================================   [注0]   我们知道,许多程式设计语言都允许在程式运行期动态地分配记忆体空间。 分配记忆体的方式多种多样,取决於该种语言的语法结构。但不论是哪一种语言 的记忆体分配方式,最後都要交还 [改1] 所分配的记忆体块的起始地址,即交 还 [改1] 一个指针到记忆体块的首地址。   当已经分配的记忆体空间不再需要时,换句话说当指向该记忆体块的句柄 [注1] 超出了使用范围的时候,该程式或其运行环境就应该回收该记忆体空间, 以节省宝贵的记忆体资源。   在 C,C++ 或其他程式设计语言中,无论是对象 [注2] 还是动态配置的资 源或记忆体,都必须由程式员自行声明产生和回收,否则其中的资源将消耗,造 成资源的浪费甚至当机。但手工回收记忆体往往是一项复杂而艰巨的工作。因为 要预先确定占用的记忆体空间是否应该被回收是非常困难的!如果一段程式不能 回收记忆体空间,而且在程式运行时系统中又没有了可以分配的记忆体空间时, 这段程式就只能崩溃。通常,我们把分配出去後,却无法回收的记忆体空间称为 「记忆体渗漏体(Memory Leaks)」。   以上这种程式设计的潜在危险性在 Java 这样以严谨、安全着称的语言中是 不允许的。但是 Java 语言既不能限制 [改3] 程序员编写程式的自由性,又不 能把声明对象的部分去除(否则就不是物件导向 [改4] 的程式语言了),那麽 最好的解决办法就是从 Java 程式语言本身的特性入手。於是,Java 技术提供 了一个系统级的 thread [改5],即垃圾收集器 [改6](Garbage Collection Thread),来跟踪每一块分配出去的记忆体空间,当 Java 虚拟机(Java Virtual Machine)处於空闲回圈时,垃圾收集器会自动检查每一块 [改7] 分配 出去的记忆体空间,然後自动回收每一块 [改7] 可以回收的无用的记忆体块。   垃圾收集器是一种低优先级的执行绪,在一个 Java 程式的生命周期中,它 只有在 CPU [改8] 空闲的时候才有机会运行。它有效地防止了 memory leaks [改9] 的出现,并尽可能 [改10] 地节省了宝贵的记忆体资源。但是,通过 JVM [改11] 来执行垃圾收集器的方案可以是多种多样的。   下面介绍垃圾收集器的特点和它的执行机制:   垃圾收集器系统有自己的一套方案来判断哪个记忆体块是应该被回收的、哪 个是不符合要求暂不回收的。垃圾收集器在一个 Java 程式中是自动执行的 [改12],不能强制执行。即使程式员能明确地判断出有一块记忆体已经无用了、 是应该回收的,程式员也不能强制垃圾收集器回收该记忆体块。程式员唯一能做 的就是通过调用 [改13] 方法来「建议」执行垃圾收集器;但其是否可以执行, 什麽时候执行却都是不可知的。这也是垃圾收集器的最主要的缺点。当然相对於 它给程式员带来的巨大方便性而言,这个缺点是瑕不掩瑜的。   垃圾收集器的主要特点有:   1. 垃圾收集器的工作目标是回收已经无用的对象的记忆体空间,从而避免     memory leaks 产生、节省记忆体资源、避免程式代码的崩溃。   2. 垃圾收集器判断一个对象的记忆体空间是否无用的标准是:如果该对象     不再被 [改14] 程式中任何一个「活动的部分」所引用,此时我们就说     ,该对象的记忆体空间已经无用。所谓「活动的部分」,是指程式中某     部分参与程式的调用,正在执行过程中,尚未执行完毕。   3. 垃圾收集器虽然是低优先等级的 thread [改15],但在系统可用记忆体     量过低的时候,它可能会突发地执行来挽救记忆体资源。当然其执行与     否也是不可预知的。   4. 垃圾收集器不可以被强制执行,但程式员可以通过调用 System.gc() 方     法来建议执行垃圾收集器。   5. 不能保证一个无用的对象一定会被垃圾收集器收集,也不能保证垃圾收     集器在一段 Java 语言代码中一定会执行。因此在程式执行过程中被分     配出去的记忆体空间可能会一直保留到该程式执行完毕,除非该空间被     重新分配或被其他方法回收。由此可见,完全彻底地根绝 memory leaks     的产生也是不可能的。但是请不要忘记,Java 的垃圾收集器毕竟使程式     员从手工回收记忆体空间的繁重工作中解脱了出来。设想一个程式员要     用 C 或 C++ 来编写一段 10 万行语句的程式码 [改16],那麽他一定会     充分体会到 Java 垃圾收集器的优点!   6. 同样没有办法预知在一组均符合垃圾收集器收集标准的对象中,哪一个     会被首先收集。   7. 回圈引用对象不会影响其被垃圾收集器收集。   8. 可以通过将对象的引用变数(reference variables,即句柄 handles)     设定为 null [改17],来暗示垃圾收集器来收集该对象。但此时,如果     该对象连接有事件监听器(典型的 AWT 组件),那它还是不可以被收集     。所以在设一个引用变数为 null 值之前,应注意该引用变数指向的对     像是否被监听,若有,要首先除去监听器,然後才可以赋空值。   9. 每一个对象都有一个 finalize() 方法,这个方法是从 Object 类继承     来的。   10. finalize() 方法用来回收记忆体以外的系统资源,就像是文件处理器     和网路连接器。该方法的调用顺序和用来调用该方法的对象的创建顺序     是无关的。换句话说,书写程式时该方法的顺序和方法的实际调用顺序     是不相干的。请注意这只是 finalize() 方法的特点。   11. 每个对象只能调用 finalize() 方法一次。如果在 finalize() 方法执     行时产生异常(exception),则该对象仍可以被垃圾收集器收集。   12. 垃圾收集器跟踪每一个对象,收集那些不可到达的对象(即该对象没有     被程式的任何「活的部分」所调用),回收其占有的记忆体空间。但在     进行垃圾收集的时候,垃圾收集器会调用 finalize() 方法,通过让其     他对象知道它的存在,而使不可到达的对象再次「复苏」为可到达的对     象。既然每个对象只能调用一次 finalize() 方法,所以每个对象也只     可能「复苏」一次。   13. finalize() 方法可以明确地被调用,但它却不能进行垃圾收集。   14. finalize() 方法可以被重载(overload),但只有具备初始的     finalize() 方法特点的方法才可以被垃圾收集器调用。   15. 子类别 [改18] 的 finalize() 方法可以明确地调用父类别 [改18] 的     finalize() 方法,作为该子类对象的最後一次适当的操作。但 Java     编译器却不认为这是一次覆盖操作(overriding),所以也不会对其调     用进行检查。   16. 当 finalize() 方法尚未被调用时,System.runFinalization() 方法     可以用来调用 finalize() 方法,并实现相同的效果,对无用对象进行     垃圾收集。   17. 当一个方法 [注3] 执行完毕,其中的局部变数就会超出使用范围,此     时可以被当作垃圾收集。但以後每当该方法再次被调用时,其中的局部     变数便会被重新创建。   18. Java 语言使用了一种「标记交换区的垃圾收集演算法」。该演算法会     遍历程式中每一个对象的句柄,为被引用的对象做标记,然後回收尚未     做标记的对象。所谓遍历可以简单地理解为「检查每一个」。 [注4]   19. Java 语言允许程式员为任何方法添加 finalize() 方法,该方法会在     垃圾收集器交换回收对象之前被调用。但不要过分依赖该方法对系统资     源进行回收和再利用,因为该方法调用後的执行结果是不可预知的。   通过以上对垃圾收集器特点的了解,你应该可以明确垃圾收集器的作用,和 垃圾收集器判断一块记忆体空间是否无用的标准。简单地说,当你为一个对象赋 值为 null 并且重新定向了该对象的引用者,此时该对象就符合垃圾收集器的收 集标准。   判断一个对像是否符合垃圾收集器的收集标准,这是SUN公司程式员认证考 试中垃圾收集器部分的重要考点(可以说,这是唯一的考点)。所以,考生在一 段给定的代码中,应该能够判断出哪个对象符合垃圾收集器收集的标准,哪个不 符合。下面结合几种认证考试中可能出现的题型来具体讲解:   Object obj = new Object ();   我们知道,obj 为 Object 的一个句柄。当出现 new 关键字时,就给新建 的对象分配记忆体空间,而 obj 的值就是新分配的记忆体空间的首地址,即该 对象的值(请特别注意,对象的值和对象的内容是不同含义的两个概念:对象的 值就是指其记忆体块的首地址,即对象的句柄;而对象的内容则是其具体的记忆 体块)。此时如果有 obj = null;则 obj 指向的记忆体块此时就无用了,因为 下面再没有调用该变数了。   请再看以下三种认证考试时可能出现的题型:      程式段1:   1. fobj = new Object ();   2. fobj.Method();   3. fobj = new Object( ) ;   4. fobj.Method( ) ;   问:这段代码中,第几行的 fobj 符合垃圾收集器的收集标准?   答:第 3 行。因为第 3 行的 fobj 被赋了新值,产生了一个新的对象,即 换了一块新的记忆体空间,也相当於为第 1 行中的 fobj 赋了 null 值。这种 类型的题在认证考试中是最简单的。   程式段2:   1. Object sobj = new Object ();   2. Object sobj = null;   3. Object sobj = new Object ();   4. sobj = new Object ();   问:这段代码中,第几行的记忆体空间符合垃圾收集器的收集标准?   答:第 1 行和第 3 行。因为第 2 行为 sobj 赋值为 null,所以在此第 1 行的 sobj 符合垃圾收集器的收集标准。而第 4 行相当於为 sobj 赋值为 null,所以在此第 3 行的 sobj 也符合垃圾收集器的收集标准。   如果有一个对象的句柄 a,且你把 a 作为某个构造器的参数,即 new Constructor(a) 的时候,即使你给 a 赋值为 null,a 也不符合垃圾收集器的 收集标准。直到由上面构造器构造的新对象被赋空值时,a 才可以被垃圾收集器 收集。   程式段3:   1. Object aobj = new Object ();   2. Object bobj = new Object ();   3. Object cobj = new Object ();   4. aobj = bobj;   5. aobj = cobj;   6. cobj = null;   7. aobj = null;   问:这段代码中,第几行的记忆体空间符合垃圾收集器的收集标准?   答:第 7 行。注意这类题型是认证考试中可能遇到的最难题型了。   行 1~3 分别创建了 Object 类的三个对象:aobj,bobj,cobj   行 4:此时对象 aobj 的句柄指向 bobj,所以该行的执行不能使 aobj 符 合垃圾收集器的收集标准。   行 5:此时对象 aobj 的句柄指向 cobj,所以该行的执行不能使 aobj 符 合垃圾收集器的收集标准。   行 6:此时仍没有任何一个对象符合垃圾收集器的收集标准。   行 7:对象 cobj 符合了垃圾收集器的收集标准,因为 cobj 的句柄指向单 一的地址空间。在第 6 行的时候,cobj 已经被赋值为 null,但由 cobj 同时 还指向了 aobj(第 5 行),所以此时 cobj 并不符合垃圾收集器的收集标准。 而在第 7 行,aobj 所指向的地址空间也被赋予了空值 null,这就说明了,由 cobj 所指向的地址空间已经被完全地赋予了空值。所以此时 cobj 最终符合了 垃圾收集器的收集标准。但对於 aobj 和 bobj,仍然无法判断其是否符合收集 标准。   总之,在Java语言中,判断一块记忆体空间是否符合垃圾收集器收集标准的 标准只有两个:   1. 给对象赋予了空值null,以下再没有调用过。   2. 给对象赋予了新值,既重新分配了记忆体空间。   最後再次提醒一下,一块记忆体空间符合了垃圾收集器的收集标准,并不意 味着这块记忆体空间就一定会被垃圾收集器收集。 ========================================================================== 修改部份 1. 返回→交还 2. 死机→当机 3. 限制→限制 4. 面向对象→物件导向 5. 线程→ Thread(其後不再注明) 6. 垃圾收集器线程→垃圾收集器(其後不再注明) 7. 每一快→每一块 8. 记忆体→CPU 9. 记忆体渗漏体→memory leaks(其後不再注明) 10. 极大可能→尽可能 11. Java虚拟机→JVM(其後不再注明) 12. 的执行是自动的→是自动执行的 13. System. gc→System.gc()(其後不再注明) 14. 不能再被→不再被 15. 作为低优先级的线程运行→低优先等级的 thread 16. 代码→程式码(其後不再注明) 17. 初始化为null值→设定为 null 18. 类→类别 注解部份 0. 把第一段的废话砍掉 1. handles, reference variables 2. 应该是 reference (上述两个,如果有更好的中文翻译,恳请赐教) 3. 应该是 method 4. 详细演算法内容可参考下列网址 http://www.microsoft.com/taiwan/msdn/columns/DoNet/garbage_collection.htm -- 侃侃长论鲜窒碍 网站:http://www.psmonkey.idv.tw 众目睽睽无心颤 个人版:telnet://legend.twbbs.org 茕居少聊常人事 杀头容易告白难 欢迎参观 Java 版(@ptt.cc) \囧/ --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.126.172.167 ※ 编辑: PsMonkey 来自: 59.126.172.167 (08/09 22:06)







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Soft_Job站内搜寻

TOP