`
javawebsoa
  • 浏览: 424266 次
社区版块
存档分类
最新评论

Java学习笔记(对象的释放)

 
阅读更多

对于基本类型变量来说,因为都被分配在内存栈中,因此释放不是问题,而且都会被及时地释放.但对于引用类型来说,就不一样了.
Java提供了基本的对象内存回收机制-垃圾回收器.下面看看如何工作:
首先我们必须了解一点,引用类型的变量和基本类型的变量一样,都是被分配到内存栈里的,只是引用类型的变量在栈中保存的是
一个引用地址(指针),该引用地址所指的堆内存就是实际的对象存放区。
Java的垃圾回收器对于Java程序来说是外部程序,是独立运行的,因此必须有一种机制,让垃圾回收器知道哪些对象(堆中)
是不再被用的,最简单的方法当然是对对象引用计数:
一个对象被一个对象变量引用,其对象引用计数就加1,如果一个对象的引用变量(在栈中)超出生存期,被释放时,对象引用计数
就减1,这样,垃圾回收器就可以根据对象引用计数来判断对象是否可以被收回。看起来这种方法确实比较简单,但实际上,
这种方式还是有很多问题的:
1)如果对象变量都在栈中,上述机制当然没问题。但实际上对象变量可以是另一个对象的成员,而且对象本身也可以包含其它
对象类型的成员变量,这样就会形成一个复杂的引用关系网,这个引用关系网还可能会包含循环引用的情况,就会很容易导致一
些对象在整个程序运行期间都不会被回收,从而产生大量的内存泄露;
2)同步问题。垃圾回收器工作时,如果程序也在工作,也在分配或操作对象,比如一个对象的引用计数虽然为0,垃圾
回收器回收该对象,但同时,这个对象又被引用到一个新的对象变量,就会产生不可预知的错误。为了防止这种冲突,垃圾回
收器工作时程序就必须停止工作。这就会带来另外一个问题,程序运行效率降低。

现在这种利用对象引用计数方式的垃圾回收方式已经很少单独使用。

另外一种方法是采用对象跟踪技术的方法:
垃圾回收器工作时,从程序栈内存中的引用变量开始,遍历对象引用,标记对象可达。那么不可达的对象都可以回收掉。
这种方法解决了循环引用的问题,回收效率比较高,但也同样有以下问题:
1)没有解决垃圾回收器和程序之间的同步问题,垃圾回收器工作期间程序必须停止运行;
2) 每次垃圾回收时,都需要遍历所有的对象,用时会比较长;

当然还有很多垃圾回收策略,大家可以搜一下,虽然垃圾回收对于程序员来说,大部分时间是透明的,但理解这些机制,其实也可以
对我们处理实际问题时提供一种借鉴。
无论是那种回收机制,对于程序员来说,有两个地方是必须关注的:
1)我们的对象什么时候被回收(垃圾回收器运行的不可控);
2)Java产生的对象没问题,但我们自己分配的内存(主要是调用其它语言代码库,比如C++)怎么释放。
垃圾回收器工作的触发是根据其对内存使用的监控来确定的,当内存空间小于某个阀值时才触发垃圾回收。对于大部分的情况,这应该
不是问题,但如果我们的对象使用了第三方稀缺资源,比如数据库链接,或者我们需要在对象释放的时候做一些清除(比如擦除在界面上的
绘图)工作,我们该怎么办?一种办法当然是主动出击,比如数据库链接,打印机释放等,但有些情况下,我们还是无法主动出击的,比如
一个对象使用了数据库链接,但这个对象被多个其它对象共享,你就很难主动出击释放链接了。对于这种情况,Java提供了另外一种机制,
就是为每个对象提供一个finalize()方法,该方法由垃圾回收器调用(虽然你自己也可以调用,但不建议这样做,原因同无法主动出击类似)。
这样对于对象释放后需要做的清理工作就可以在这个方法中进行。但要注意垃圾回收器对finalize()方法的调用是有限制的,比如每个对象只调用
一次这个方法,因此,我们必须留意对象"复活"所带来的问题。
对于什么时候我们的对象会被回收的问题,虽然我们可以调用System.gc()来建议(注意,只是建议)垃圾回收器进行回收工作,但实际上
对我们来说,还是不可控的,因此:
1)对于资源,特别是稀缺资源的释放,我们还是应该尽量主动出击来完成;
2)对于调用其它语言代码库,也尽量主动出击进行对象释放,如果不行,至少也要在finalize()方法中完成;

下面的例子,是抄书本上的,用来演示垃圾回收的不确定性(我稍微做了修改):

public class Chair {
	
		static boolean gcrun = false;
		static boolean f = false;
		static int created = 0;
		static int finalized = 0;
		int i;
		Chair() {
		i = ++created;
		if(created == 47)
		System.out.println("Created 47");
		}
		protected void finalize() {
		if(!gcrun) {
		gcrun = true;
		System.out.println(
		"Beginning to finalize after " +
		created + " Chairs have been created=>"+i);
		}
		if(i == 47) {
		System.out.println(
		 "Finalizing Chair #47, " +
		 "Setting flag to stop Chair creation");
		 f = true;
		}
		finalized++;
		if(finalized >= created)
		System.out.println("All " + finalized + " finalized");
		}
}


public class GarbageC {
	public static void main(String[] args) {
		
		while(!Chair.f) {
		   new Chair();
		   new String("To take up space");
		}
		System.out.println(
		"After all Chairs have been created:\n" +
		"total created = " + Chair.created +
		", total finalized = " + Chair.finalized);
		String theMethString ="after";
		if(theMethString.equals("before")) {
		 	System.out.println("gc():");
			System.gc();
		 	System.out.println("runFinalization():");
			System.runFinalization();
		}
		System.out.println("bye!");
		if(theMethString.equals("after"))
		  System.runFinalizersOnExit(true);
		}
}



分享到:
评论

相关推荐

    Java学习笔记PPT

    总的来说,这份"Java学习笔记PPT"是初学者和进阶者学习Java的理想资料,覆盖了语言基础、面向对象、集合框架、异常处理、I/O系统、多线程等多个方面,旨在帮助读者系统地掌握Java编程技能,并能灵活运用到实际项目中...

    java学习笔记总结.doc

    这篇文档是个人的Java学习笔记总结,旨在帮助0基础的学习者从零开始掌握Java基础知识,并逐步成为专业的Java开发者。以下是笔记中涉及的一些关键知识点: 1. **Java开发环境的设置**: 要开始Java编程,首先需要...

    Think In Java 学习笔记

    《Think In Java 学习笔记》 在Java编程语言中,对象是核心概念,它们代表着程序中的实体和行为。对象具有状态、行为和标识,是现实世界概念在软件中的映射。对象的状态由其内部的属性(或称数据成员)表示,行为则...

    Thinking in Java 自学笔记——第二章 一切皆对象

    ### Thinking in Java 自学笔记——第二章 一切皆对象 #### 重要概念解析 ##### 2.1 用引用操纵对象 在Java中,一切都被视为对象,这意味着无论是字符串、数字还是其他数据类型都可以被视为对象来进行操作。当...

    java基础(超详细。。学习笔记) 公司内部资料!保密哦!!!

    本篇学习笔记将深入探讨Java的基础概念,主要包括初始化、数据类型、对象、变量类型、集合类、泛型、垃圾回收、方法重载与重写以及static关键字。 首先,初始化是程序执行的起点,涉及到变量的分配和设定初始值。在...

    淡淡Java学习笔记

    "淡淡Java学习笔记"显然是一份记录了作者学习Java过程中的思考与理解的文档,通过这份笔记,我们可以一同探索Java的核心概念和重要知识点。 首先,Java的学习通常从基础语法开始,包括数据类型(如整型、浮点型、...

    java学习详细笔记

    ### Java学习详细笔记 #### 1. 什么是JDBC? JDBC(Java Database Connectivity)是Java平台中的数据库连接技术,它允许Java程序连接各种类型的数据库并执行SQL命令。JDBC由一组接口和类组成,这些接口和类为开发...

    JAVA学习笔记详解

    ### JAVA学习笔记详解 #### 第一讲 Java语言概述 ##### 课前思考: 1. **新的编程语言是否需要借鉴以前的编程语言?** - 新的编程语言在设计时往往会借鉴已有语言的成功经验和失败教训。Java 作为一种相对较新的...

    java学习笔记,好好学习

    这篇“java学习笔记”可能包含了从基础到进阶的各种Java编程概念和技术。以下是对这些笔记可能涵盖的一些关键知识点的详细说明: 1. **Java基础知识**: - **语法**:包括变量声明、数据类型(如整型、浮点型、...

    java学习笔记-基础

    ### Java学习笔记——基础知识详解 #### 一、Java开发环境(JDK)与运行环境(JRE) Java技术的核心在于其强大的跨平台能力,这主要得益于Java的两大环境:JDK(Java Development Kit)和JRE(Java Runtime ...

    学习笔记之对象的创建(Java)

    ### 学习笔记之对象的创建(Java) #### Java技术与Java虚拟机 Java作为一种广泛使用的编程语言,其独特之处在于“一次编写,到处运行”的理念。这一特性主要得益于Java虚拟机(JVM)的存在。Java技术主要包括以下几...

    Java学习笔记和例子

    Java学习笔记和例子 Java是一种广泛应用于企业级开发的编程语言,具有平台独立性、对象oriented、分布式、健壮的安全性和动态性的特点。下面是Java学习笔记和例子的总结: 目录一.Javabean Javabean是一种特殊的...

    Java相关课程系列笔记之一Java学习笔记.doc

    总结,这份Java学习笔记全面地介绍了从入门到进阶的Java知识,旨在帮助学习者扎实基础,理解面向对象编程的核心概念,并深入学习Java SE的高级特性。同时,对JavaScript的了解也能增强开发者对整个Web开发的理解。...

    java学习笔记.docx

    ### Java学习笔记知识点详解 #### JDBC (Java Database Connectivity) **加载数据库驱动** - 在使用JDBC之前,首先需要加载对应的数据库驱动。对于SQL Server来说,通常使用的类名为`...

    Java学习笔记_垃圾回收

    Java垃圾回收(Garbage Collection, 简称GC)是Java编程语言中一项重要的自动内存管理机制,...通过阅读"Java学习笔记_垃圾回收.pdf",你将进一步深入理解这个主题,掌握如何在实际项目中有效利用和优化垃圾回收机制。

    java私塾学习笔记整理

    ### Java私塾学习笔记整理 #### 第一章:Java入门 **一、Java是什么?** Java是一种广泛使用的高级编程语言,由Sun Microsystems于1995年推出。它旨在为跨平台开发提供一种通用的语言环境,使开发者能够在任何...

Global site tag (gtag.js) - Google Analytics