`
chenyunhong
  • 浏览: 140311 次
  • 性别: Icon_minigender_1
  • 来自: 真的不知道
社区版块
存档分类
最新评论

垃圾搜索机制

    博客分类:
  • Java
阅读更多

通常,我们把分配出去后,却无法回收的内存空间称为"内存渗漏体(Memory Leaks)"。
以上这种程序设计的潜在危险性在Java这样以严谨、安全著称的语言中是不允许的。但是Java语言既不能限制程序员编写程序的自由性,又不能把声明对象的部分去除(否则就不是面向对象的程序语言了),那么最好的解决办法就是从Java程序语言本身的特性入手。于是,Java技术提供了一个系统级的线程(Thread),即垃圾收集器线程(Garbage Collection Thread),来跟踪每一块分配出去的内存空间,当Java 虚拟机(Java Virtual Machine)处于空闲循环时,垃圾收集器线程会自动检查每一快分配出去的内存空间,然后自动回收每一快可以回收的无用的内存块。
垃圾收集器线程是一种低优先级的线程,在一个Java程序的生命周期中,它只有在内存空闲的时候才有机会运行。它有效地防止了内存渗漏体的出现,并极大可能地节省了宝贵的内存资源。但是,通过Java虚拟机来执行垃圾收集器的方案可以是多种多样的。
下面介绍垃圾收集器的特点和它的执行机制:
垃圾收集器系统有自己的一套方案来判断哪个内存块是应该被回收的,哪个是不符合要求暂不回收的。垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回收的,程序员也不能强制垃圾收集器回收该内存块。程序员唯一能做的就是通过调用System. gc 方法来"建议"执行垃圾收集器,但其是否可以执行,什么时候执行却都是不可知的。这也是垃圾收集器的最主要的缺点。当然相对于它给程序员带来的巨大方便性而言,这个缺点是瑕不掩瑜的。
垃圾收集器的主要特点有:
1.垃圾收集器的工作目标是回收已经无用的对象的内存空间,从而避免内存渗漏体的产生,节省内存资源,避免程序代码的崩溃。
2.垃圾收集器判断一个对象的内存空间是否无用的标准是:如果该对象不能再被程序中任何一个"活动的部分"所引用,此时我们就说,该对象的内存空间已经无用。所谓"活动的部分",是指程序中某部分参与程序的调用,正在执行过程中,尚未执行完毕。
3.垃圾收集器线程虽然是作为低优先级的线程运行,但在系统可用内存量过低的时候,它可能会突发地执行来挽救内存资源。当然其执行与否也是不可预知的。
4.垃圾收集器不可以被强制执行,但程序员可以通过调用System. gc方法来建议执行垃圾收集器。
5.不能保证一个无用的对象一定会被垃圾收集器收集,也不能保证垃圾收集器在一段Java语言代码中一定会执行。因此在程序执行过程中被分配出去的内存空间可能会一直保留到该程序执行完毕,除非该空间被重新分配或被其他方法回收。由此可见,完全彻底地根绝内存渗漏体的产生也是不可能的。但是请不要忘记,Java的垃圾收集器毕竟使程序员从手工回收内存空间的繁重工作中解脱了出来。设想一个程序员要用C或C++来编写一段10万行语句的代码,那么他一定会充分体会到Java的垃圾收集器的优点!
6.同样没有办法预知在一组均符合垃圾收集器收集标准的对象中,哪一个会被首先收集。
7.循环引用对象不会影响其被垃圾收集器收集。
8.可以通过将对象的引用变量(reference variables,即句柄handles)初始化为null值,来暗示垃圾收集器来收集该对象。但此时,如果该对象连接有事件监听器(典型的 AWT组件),那它还是不可以被收集。所以在设一个引用变量为null值之前,应注意该引用变量指向的对象是否被监听,若有,要首先除去监听器,然后才可以赋空值。
9.每一个对象都有一个finalize( )方法,这个方法是从Object类继承来的。
10.finalize( )方法用来回收内存以外的系统资源,就像是文件处理器和网络连接器。该方法的调用顺序和用来调用该方法的对象的创建顺序是无关的。换句话说,书写程序时该方法的顺序和方法的实际调用顺序是不相干的。请注意这只是finalize( )方法的特点。
11.每个对象只能调用finalize( )方法一次。如果在finalize( )方法执行时产生异常(exception),则该对象仍可以被垃圾收集器收集。
12.垃圾收集器跟踪每一个对象,收集那些不可到达的对象(即该对象没有被程序的任何"活的部分"所调用),回收其占有的内存空间。但在进行垃圾收集的时候,垃圾收集器会调用finalize( )方法,通过让其他对象知道它的存在,而使不可到达的对象再次"复苏"为可到达的对象。既然每个对象只能调用一次finalize( )方法,所以每个对象也只可能"复苏"一次。
13.finalize( )方法可以明确地被调用,但它却不能进行垃圾收集。
14.finalize( )方法可以被重载(overload),但只有具备初始的finalize( )方法特点的方法才可以被垃圾收集器调用。
15.子类的finalize( )方法可以明确地调用父类的finalize( )方法,作为该子类对象的最后一次适当的操作。但Java编译器却不认为这是一次覆盖操作(overriding),所以也不会对其调用进行检查。
16.当finalize( )方法尚未被调用时,System. runFinalization( )方法可以用来调用finalize( )方法,并实现相同的效果,对无用对象进行垃圾收集。
17.当一个方法执行完毕,其中的局部变量就会超出使用范围,此时可以被当作垃圾收集,但以后每当该方法再次被调用时,其中的局部变量便会被重新创建。
18.Java语言使用了一种"标记交换区的垃圾收集算法"。该算法会遍历程序中每一个对象的句柄,为被引用的对象做标记,然后回收尚未做标记的对象。所谓遍历可以简单地理解为"检查每一个"。
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值。这种类型的题在认证0考试中是最简单的。
程序段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.给对象赋予了新值,既重新分配了内存空间。
最后再次提醒一下,一块内存空间符合了垃圾收集器的收集标准,并不意味着这块内存空间就一定会被垃圾收集器收集。
摘自Java中文站

分享到:
评论

相关推荐

    垃圾回收机制面试题·.docx

    ### 垃圾回收机制详解 #### 一、引言 在现代软件开发中,内存管理一直是程序设计中的一项重要任务。特别是在高级编程语言中,如何有效地管理和释放内存资源成为了衡量一个程序性能的关键因素之一。Java作为一种...

    JVM的工作原理及垃圾回收机制介绍

    ### JVM工作原理及垃圾回收机制详解 #### 一、JVM概述及原理 **1.1 JVM概述** Java Virtual Machine (JVM),即Java虚拟机,是一种虚构的计算机,在实际的计算机硬件上仿真模拟出的一套完整的计算机系统,用于执行...

    Java垃圾回收机制简述

    "Java垃圾回收机制简述" Java垃圾回收机制是Java虚拟机(JVM)中的一种机制,用于释放垃圾占用的空间,以便提高系统性能和避免内存泄露。在Java中,垃圾回收机制主要解决两个问题:如何确定某个对象是“垃圾”?...

    浅谈JAVA垃圾回收机制.pdf

    浅谈 JAVA 垃圾回收机制 Java 垃圾回收机制是 Java 语言中的一种自动内存管理机制,它可以自动回收内存中的垃圾,避免代码运行时由于忘记释放对象而带来的内存泄漏问题。 Java 中的垃圾回收机制主要通过两种算法来...

    单例模式与垃圾回收机制

    ### 单例模式与垃圾回收机制 #### 一、引言 在软件开发领域,设计模式作为一种被广泛接受的最佳实践,对于提高代码质量和可维护性起着重要作用。单例模式作为23种经典设计模式之一,确保了某个类只有一个实例,并...

    java垃圾回收(gc)机制详解.pdf

    Java垃圾回收(GC)机制是Java语言管理内存的自动化机制,它能够自动释放不再使用的内存空间,从而避免内存泄漏和程序崩溃等问题。在介绍Java GC机制之前,我们首先要了解垃圾回收的目的和意义。在任何程序中,内存...

    你应该了解的Java垃圾回收机制.docx

    Java垃圾回收机制是Java语言的核心特性之一,它自动管理程序的内存,避免了程序员手动管理内存可能导致的内存泄漏和溢出等问题。Java的垃圾回收机制主要关注如何识别和释放不再使用的对象,以便回收它们占用的内存供...

    浅析PHP7 的垃圾回收机制

    垃圾回收机制是现代编程语言内存管理的重要组成部分,它通过自动检测和释放程序中不再使用的内存块,帮助程序员减轻内存管理的负担,避免内存泄漏等问题。PHP7中的垃圾回收机制针对的是PHP动态类型系统中的复杂数据...

    C++实现垃圾回收器

    C++作为一种静态类型、编译式的语言,其标准库并不内置垃圾回收机制,程序员需要手动管理内存。然而,为了在C++中实现类似的功能,我们可以构建自定义的垃圾回收器。本话题将深入探讨如何用C++实现一个简单的单线程...

    C语言,基于mark-sweep算法实现的垃圾回收机制.zip

    本主题聚焦于C语言中如何利用mark-sweep算法来实现垃圾回收机制。C语言本身并不支持内置的垃圾回收,但通过自定义的实现,我们可以为C程序引入这一功能。 **一、什么是Mark-Sweep算法** Mark-Sweep算法是最早的...

    jvm垃圾回收机制详解,学习过程,如有侵权请联系删除

    可达性分析算法,又称根搜索算法,通过从GC Roots(如虚拟机栈中的引用、静态属性、常量引用和JNI引用)出发,遍历所有可达的对象,无法到达的对象被视为垃圾。 Java提供了四种不同强度的引用:强引用、软引用、弱...

    C#内存(垃圾)自动回收机制借鉴.pdf

    CLR为托管代码提供了一系列服务,其中垃圾回收机制是一个关键特性,它自动化了内存管理,避免了内存泄漏和资源浪费。 在C#中,当我们使用`new`关键字创建对象时,内存会在托管堆上分配。托管堆是由CLR在应用程序...

    关于垃圾收集的一些话

    在探讨Java垃圾收集(GC)机制时,我们首先要了解与C++在内存管理和对象分配方面的根本区别。C++倾向于在堆栈上分配对象,这允许程序在进入作用域时快速分配和释放内存,因为堆栈的内存管理是顺序的且不需要复杂的...

    JAVA垃圾回收面试个人总结.doc

    Java垃圾回收机制是Java编程中一个非常重要的概念,尤其在面试和实际开发中常常被讨论。垃圾回收(Garbage Collection, GC)是Java虚拟机自动管理内存的一种方式,旨在自动识别并释放不再使用的对象,从而避免内存...

    垃圾分类指南小程序源码分享

    而“微信小程序”则意味着这个应用是在微信平台上运行,无需下载安装,用户只需在微信内搜索即可使用,具有很高的便捷性。 从压缩包子文件的文件名来看,如"_1123949441_260.wxapkg"和"_1542146608_33.wxapkg",...

    java垃圾回收及内存泄漏.pptx

    ### Java垃圾回收及内存泄漏知识点详解 #### 一、Java内存管理 1. **运行时数据区**:...通过对内存管理的理解和垃圾回收机制的学习,开发者能够更好地编写高效、稳定的Java程序,并有效避免内存泄漏等问题的发生。

    易语言源码易语言垃圾清理源码.rar

    7. 优化算法:为了提高清理效率,源码可能采用特定的搜索算法,如深度优先或广度优先搜索,以快速定位垃圾文件。 8. 多线程:在清理大量文件时,多线程可以提高程序运行速度。易语言提供了多线程支持,让开发者可以...

Global site tag (gtag.js) - Google Analytics