垃圾回收的可触及性

可触及性的3种状态:

1.可触及的:从根节点开始,可以到达这个对象。

2.可复活的:对象的所有引用都被释放,但是对象有可能在finalize()函数中复活。

3.不可触及的:对象的finalize()函数被调用,并且没有复活,那么就会进入不可触及状态,不可触及的对象不能被复活,因为finalize()函数只会被调用一次。

对象的复活

/** * Created by xxd on 2017/4/4. */public class CanReliveObj {    public static CanReliveObj obj;

@Override    protected  void finalize() throws Throwable{        super.finalize();        System.out.println("CanReliveObj finalize called");        obj = this;    }

@Override    public String toString(){        return "I am CanReliveObj";    }

public static void main(String[] args) throws InterruptedException{        obj = new CanReliveObj();        obj = null;        System.gc();        Thread.sleep(1000);        if (obj == null){            System.out.println("obj is null");        }else{            System.out.println("obj is useful");        }        System.out.println("the second gc");        obj = null;        System.gc();        Thread.sleep(1000);        if (obj == null){            System.out.println("obj is null");        }else{            System.out.println("obj is useful");        }    }}

运行结果如下

第一次将obj设置为null后,进行GC,结果obj对象被复活。

第二次将obj设置为null,并GC后,对象才被真正的回收。

这是因为在第一次GC时,在finalize()函数调用之前,虽然系统中的引用已经被清除,但是作为实例方法finalize(),对象的this引用依然会被传入方法内部,如果引用外泄,对象就会复活。

此时,对象又变为可触及状态。

而finalize()函数只会被调用一次,因此,在第二次清除对象时,对象就无机会复活,因此就会被回收。

注意:

1.finalize()函数有可能发生引用外泄,在无意中复活对象;

2.由于finalize()是被系统调用的,调用时间是不明确的,因此不是一个好的资源释放方案,推荐在try-catch-finally语句中进行资源的释放。

时间: 2024-11-10 13:56:58

垃圾回收的可触及性的相关文章

Nodejs通过Thrift操作hbase卡住原因分析及与javascript的垃圾回收机制的关系

在最近使用Nodejs通过Thrift操作hbase的时候写了个脚本,不断发送http请求,从而取得hbase下所需的数据,但是在run的过程中for循环并没有执行完全,在执行一部分后会卡住,就再也进不到hbase下取数据,出现socket hang up的错误,查了很多资料也没解决.当时认为是hbase的并发数问题,其并发数的限制导致了资源负载的极限,后来不断测试找到原因所在,其实与hbase处理并发的能力无关,真正的原因是jsvascript的垃圾回收机制使得资源使用达到瓶颈,下面是代码处理

垃圾回收简介

GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法.Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理.要请求垃圾收集,可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用. 垃圾回收可以有效的防止内存泄露,

Python中的垃圾回收机制

当我们声明一个对象的时候,例如str="abcdef",当我们不再使用str这个对象的时候,这个对象就是一个脏对象,垃圾对象,但是它还在占着内存,毕竟我们的电脑内存有限,所以应该有一个机制来回收它以及类似的对象.现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的方式.自己管理内存极其自由,可以任意申请内存,但如同一把双刃剑,为大量内存泄露,悬空指针等bug埋下隐患. 对于一个字符串.列表.类甚至数值都是对象,且定位简单易用的语言,自然不会

各种垃圾回收 (转)

1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片.由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,

python的垃圾回收机制

进程空间 进程运行时需要在内核中占据一段内存空间,用以存储程序和数据. 每个进程空间分布如下所示: 进程空间的结构 text段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域.在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等. data段:数据段(data segment)通常用来存放程序中已初始化的全局变量数据段属于静态内存分配. bss段:bss(Block Started by Symbol) 通常用来存放程序中未初始化的

java语言及其垃圾回收机制简单概述

 一.java 语言概述 Java 语言是一门纯粹的面向对象编程语言,它吸收了c++语言的各种优点.又摈弃了c++里难以理解的多继承,指针等概念因此Java语言具有功能强大和简单易用两个特征. Java语言的几个重要概念如下: J2ME:主要用于控制移动设备和信息家电等有限存储设备 J2SE:整个java技术的核心和基础, J2EE:java技术中应用最最广泛的部分,它提供了企业应用开发相关的完整的解决方案. API: 核心类库 JRE:运行Java程序所必须的环境的集合,包含JVM标准实现及J

Java深度历险(四)——Java垃圾回收机制与引用类型

Java语言的一个重要特性是引入了自动的内存管理机制,使得开发人员不用自己来管理应用中的内存.C/C++开发人员需要通过malloc/free 和new/delete等函数来显式的分配和释放内存.这对开发人员提出了比较高的要求,容易造成内存访问错误和内存泄露等问题.一个常见的问题是会产生“悬挂引用(dangling references)”,即一个对象引用所指向的内存区块已经被错误的回收并重新分配给新的对象了,程序如果继续使用这个引用的话会造成不可预期的结果.开发人员有可能忘记显式的调用释放内存

JVM垃圾回收机制总结(6) :透视Java的GC特性

1. 使用 System.gc() 可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求 Java的垃圾回收. 在命令行中有一个参数-verbosegc可以查看Java使用的堆内存的情况,它的格式:java -verbosegc classfile class TestGC { public static void main(String[] args) { new TestGC(); System.gc(); System.runFinalization(); } } class TestG

Java垃圾回收机制以及内存泄漏

原文地址 前言 在segmentfault上看到一个问题:java有完善的GC机制,那么在java中是否会出现内存泄漏的问题,以及能否给出一个内存泄漏的案例.本问题视图给出此问题的完整答案. 垃圾回收机制简介 在程序运行过程中,每创建一个对象都会被分配一定的内存用以存储对象数据.如果只是不停的分配内存,那么程序迟早面临内存不足的问题.所以在任何语言中,都会有一个内存回收机制来释放过期对象的内存,以保证内存能够被重复利用. 内存回收机制按照实现角色的不同可以分为两种,一种是程序员手动实现内存的释放