程序无法精确控制java垃圾回收的时机,但依然可以强制系统进行垃圾回收--这种强制只是通知系统进行垃圾回收, 但系统是否进行垃圾回收依然不确定。大部分时候,程序强制系统垃圾回收后总会有一些效果,强制系统垃圾回收 有如下两种方式。
1.调用System类的gc()静态方法:System.gc();
2.调用Runtime对象的gc()实例方法:Runtime.GetRuntime().gc();
 
 
public class GcTest
{
    public static void main(String[] args)
    {
        for(int i=0;i<4;i++)
        {
            new GcTest();
            System.gc();
        }
    }
    public void finalize()
    {
        System.out.println("系统正在清理GcTest对象的资源...");
    }
}
 
javac GcTest后也看不到任何输出
但使用下面命令可以看到清理垃圾的操作
 
java -verbose:gc GcTest
 
 
 
 
 
finalize方法
 在垃圾回收机制回收某个对象所占用的内存之前,通常要求程序调用适当的方法来清理资源,在没有明确指定清理资源的情况下,java提供了默认机制清理该对象的资源,这个机制就是finalize()方法。
该方法是定义在Object类里的实例方法,方法原型为:
    protected void finalize() throws Throwable
当finalize()方法返回后,对象消失,垃圾回收机制开始执行。方法原型中的throws Throwable表示它可以抛出任何类型的异常。
    任何Java类都可以重写Object类的finalize()方法,在该 方法中清理该对象占用的资源,如果程序终止之前始终没有进行垃圾回收,则不会调用失去引用对象的finalize()方法清理资源。垃圾回收机制何时调用对象的finalize()方法是完全透明的,只有当程序认为需要更多的额外内存时,垃圾回收机制才会进行垃圾回收,因此,完全有可能出现这样的一种情形,某个失去引用的对象只占用了少量内存,耐用系统没有产生严重的内存需求,因此垃圾回收机制并没有试图回收该对象所占用的资源,所以该对象的finalize()方法也不会得到调用。
 finalize()方法具有如下4个特点
1. 永远不要主动调用某个对象的finalize()方法,该方法应交给垃圾回收机制调用。
2.finalize()方法何时被调用,是否被调用具有不确定性,不要把finalize()方法当成一定会被执行的方法。
3.当JVM执行可恢复对象的finalize()方法时,可能使该对象或系统中其他对象重新变成可达状态。
4.当JVM执行finalize()方法时出现异常时,垃圾回收机制不会报告任何异常,程序继续执行
 
 
   由于finalize()方法并不一定会被执行,因此如果想清理某个类里打开的资源,则不要放在finalize()方法中 进行清理。
 
 
 
 
public class FinalizeTest
{
    private static FinalizeTest ft=null;
    public void info()
    {
        System.out.println("测试资源清理的Finalize方法");
    }
    public static void main(String[] args)throws Exception
    {
        //创建FinalizeTest对象立即进入可恢复状态
        new FinalizeTest();
        //通知系统进行资源回收
        System.gc();
        //强制垃圾回收机制调用可恢复对象的finalize()方法
        //Runtime.getRuntime().runFinalizAtion();
        System.runFinalization();
        ft.info();
    }
 
    public void finalize()
    {
        //让ft引用到试图回收的可恢复对象,即可恢复对象重新变成可达对象;
        ft=this;
    }
}
 
 
 
 
上面的程序中定义了一个FinalizeTest类,重写了该类的finalize()方法,在该方法中把需要清理的可恢复对象重新赋给了ft引用变量,从而让该可恢复对象重新就可达状态。
上面程序中的main()方法创建了一个FinalizeTest类的匿名对象,因为创建后没有把这个对象赋给任何引用变量,所以该对象立即进入可恢复状态。进入可恢复状态后,系统调用System.gc();通知系统进行垃圾回收,而System.runFinalization(); 强制系统立即调用可恢复对象的finalize()方法,再次调用ft对象的info方法。编辑运行上面程序 看到如下结果:
 
 
 
 
如果不执行System.gc()方法,程序并没有通知系统开始执行垃圾回收,因此系统通常不会立即 进行垃圾回收,也就不会调用 FinalizeTest对象的finalize()方法,这样FinalizeTest的ft类变量将依然保持为null,这样就导致了空指针异常。
上面程序中如果不执行 Runtime.getRuntime().runFinalization();
或System.runFinalization(); 由于JVM垃圾回收机制的不确定性,JVM往往并不立即调用可恢复对象的finalize()方法,这样FinalizeTest的ft类变量可能依然为null,可能依然会导致指针异常。

java学习之(垃圾回收)的更多相关文章

  1. java学习之 垃圾回收

    垃圾回收器始终以一个较低优先级的后台进程进行垃圾的回收工作,这样不会影响程序的正常工作. 通常只有当内存到达用尽的边缘而程序需要分配新的内存空间时,垃圾回收器才会执行. 垃圾回收的条件:1,垃圾回收器 ...

  2. Java学习之垃圾回收

    垃圾回收(GC) GC需要完成的三件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 为什么"GC自动化"之后还要研究GC?当需要排查各种内存溢出.内存泄漏问题时,当GC成为 ...

  3. Java学习之垃圾回收机制

    垃圾回收机制,依赖JRE和JVM,涉及操作系统中内存的分配与回收.依据所学,我猜想这种机制需要的数据结构是堆内存分配表(链),管理已分配和未分配的堆内存,对于已分配堆内存,需要知道由栈内存中的哪些变量 ...

  4. Java编程思想学习笔记_1(Java内存和垃圾回收)

    1.Java中对象的存储数据的地方: 共有五个不同的地方可以存储数据. 1)寄存器.最快,因为位于处理器的内部,寄存器按需求分配,不能直接控制. 2)堆栈.位于通用RAM,通过堆栈指针可以从处理器那里 ...

  5. 高吞吐低延迟Java应用的垃圾回收优化

    高吞吐低延迟Java应用的垃圾回收优化 高性能应用构成了现代网络的支柱.LinkedIn有许多内部高吞吐量服务来满足每秒数千次的用户请求.要优化用户体验,低延迟地响应这些请求非常重要. 比如说,用户经 ...

  6. 每日一问:讲讲 Java 虚拟机的垃圾回收

    昨天我们用比较精简的文字讲了 Java 虚拟机结构,没看过的可以直接从这里查看: 每日一问:你了解 Java 虚拟机结构么? 今天我们必须来看看 Java 虚拟机的垃圾回收算法是怎样的.不过在开始之前 ...

  7. JVM学习笔记——垃圾回收篇

    JVM学习笔记--垃圾回收篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的垃圾回收部分 我们会分为以下几部分进行介绍: 判断垃圾回收对象 垃圾回收算法 分代垃圾回收 垃圾回收器 ...

  8. Java虚拟机之垃圾回收详解一

    Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...

  9. 【java虚拟机序列】java中的垃圾回收与内存分配策略

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

  10. java中存在垃圾回收机制,但是还会有内存泄漏的问题,原因是

    答案是肯定的,但不能拿这一句回答面试官的问题.分析:JAVA是支持垃圾回收机制的,在这样的一个背景下,内存泄露又被称为“无意识的对象保持”.如果一个对象引用被无意识地保留下来,那么垃圾回收器不仅不会处 ...

随机推荐

  1. PHP注释有意思的排列

    <?php // // _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = /O // ____/`---'\___ ...

  2. VB脚本调用exe应用程序并传递参数

    VB脚本调用应用程序,并传递参数给exe应用程序: Private Sub CommandButton1_Click() Dim a a = Shell("D:\\ExperimentLin ...

  3. JavaScript权威指南 第二章 词法结构

    这章主要把保留字说一下 JavaScript 把一些标识符拿出来用做自己的关键字.因此,就不能再在程序中把这些关键字用做标识符了: break delete function return typeo ...

  4. (XAML)"XXXX" does not exist in the namespace "clr-

    Error 139 Assembly 'System.Activities.Core.Presentation' was not found. Verify that you are not miss ...

  5. js复习(二)

    一.window.document对象(一)找元素 docunment.getElementById("id"):根据id找,最多找一个: docunment.getElement ...

  6. ylbtech-Unitity-CS-Arrays:数组

    ylbtech-Unitity-CS-Arrays:数组 1.A,效果图返回顶部   1.B,源代码返回顶部 1.B.1, using System; class DeclareArraysSampl ...

  7. DTD限制XML文件

    需要通过使用Microsoft Visual Studio 2010.XMLSpy或者eclipse软件来检查校验 文件中有中文,需要存为utf-8编码 book.dtd <!ELEMENT 书 ...

  8. VVDocumenter-Xcode 规范注释生成器 插件之安装调试适应新版本

    1.下载地址: 很多时候,为了快速开发,很多的技术文档都是能省则省,这个时候注释就变得异常重要,再配合Doxygen这种注释自动生成文档的,就完美了.但是每次都要手动输入规范化的注释,着实也麻烦,但有 ...

  9. CSS语法与用法小字典

    前言:这是上学时期对CSS学习的整理,一直没见过光,由于不是专门做前端开发的,难免写不到重点,但对于看懂CSS,和掌握一些基本的用法,熟悉里面的门路还是大有裨益的.由于是从word中贴过来的,排版和格 ...

  10. [Flex] IFrame系列 —— IFrame嵌入html后Alert弹出窗口被IFrame遮挡问题

    <?xml version="1.0" encoding="utf-8"?> <!--- - - - - - - - - - - - - - ...