程序无法精确控制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. C++11的新类型转换方法

    转载自 http://blog.csdn.net/luoweifu/article/details/20493177 基于C++11标准 如果你用的编译器是基于最新的C++11标准,那么这个问题就变的 ...

  2. PHP转换UTF-8和GB2312的URL编码(转)

    目前WEB的应用中, UTF-8编码和GB2312编码是并存在的,例如百度(baidu.com)和谷歌(google.com)的URL编码分别是GB2312编码和UTF-8编码.由于编码并存引起的乱码 ...

  3. [Vue]学习中遇到的疑点

    computed:计算属性,官方api上说计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算.但是经过测试并没有缓存.案例: computed: { now: function () { c ...

  4. hdu 5698 瞬间移动(排列组合)

    这题刚看完,想了想,没思路,就题解了 = = 但不得不说,找到这个题解真的很强大,链接:http://blog.csdn.net/qwb492859377/article/details/514781 ...

  5. Linux命令(20)查看当前网速

    Linux查看网络即时网速 sar -n DEV 1 100 1代表一秒统计并显示一次 100代表统计一百次 还可以使用ntop工具

  6. U8Bom查询

    select temp.*,Inventory.cInvCode,Inventory.cInvName,Inventory.cInvStd from ( select b.InvCode as 'PI ...

  7. rand srand

    题外:先定义一个指针变量int *a; 再将整数b的地址赋给指针变量 a=&b ;    谨记指针变量a只是地址 *a相当于整数 之后*a 就可以表示 指向b了 也可以在定义的时候初始化 in ...

  8. git config(转载)

    From:http://www.g2w.me/2013/10/cache-github-credential-for-https-repository/ http://openwares.net/li ...

  9. 区分DPI、分辨率(PPI)、图像的物理大小、像素宽度

    分辨率都知道,越高越清晰. 一.描述分辨率的单位有:    dpi(点每英寸).lpi(线每英寸)和ppi(像素每英寸).但只有lpi是描述光学分辨率的尺度的.虽然dpi和ppi也属于分辨率范畴内的单 ...

  10. javascript代码注意事项

    1 代码行末要加分好.原因<<javascript高级程序设计第三版21页第三行>> 2 初始化变量应该加上默认值因为使用typeof时 未声明和声明为初始化的值都返回unde ...