概述
一、JAVA垃圾回收机制概述
在VB、C++等某些程序设计语言中,无论是对象还是动态配置的资源或内存,都必须由程序员自行声明产生和回收,否则其中的资源将不断消耗,造成资源的浪费甚至死机。由于要预先确定占用的内存空间是否应该被回收是非常困难的,这就导致手工回收内存往往是一项复杂而艰巨的工作。因此,当使用这些程序设计语言编程时,程序员不仅要考虑如何实现算法以满足应用,还要花费许多精力考虑合理使用内存避免系统崩溃。
针对这种情况,JAVA语言建立了垃圾回收机制。JAVA是纯粹的面向对象的编程语言,其程序以类为单位,程序运行期间会在内存中创建很多类的对象。这些对象在完成任务之后,JAVA的垃圾回收机制会自动释放这些对象所占用的空间,使回收的内存能被再次利用,提高程序的运行效率。垃圾回收不仅可以提高系统的可靠性、使内存管理与类接口设计分离,还可以使开发者减少了跟踪内存管理错误的时间,从而把程序员从手工回收内存空间的繁重工作中解脱出来。
JAVA垃圾回收机制另一个特点是,进行垃圾回收的线程是一种低优先级的线程,在一个Java程序的生命周期中,它只有在内存空闲的时候才有机会运行。
下面本文从“对象的失去引用”和“对象离开作用域”这两个方面进行分析,探讨JAVA程序中的对象什么时候可以被当作垃圾来进行回收。
二、对象的失去引用
通过下面的一段JAVA程序(例1),我们可以讨论程序中的对象是否已经符合垃圾回收的条件。请注意,我们只是讨论某个对象是否符合被回收的条件,这并不意味着该对象将被立即回收,关于这一点,本文后面还将进一步说明。
例1:
1. class Computer{ }
2. public class GarbageCollector {
3. Computer makeComputer() {
4. Computer tempComputer = new Computer ();
5. return tempComputer;
6. }
7. public static void main (String args[]) {
8. GarbageCollector t = new GarbageCollector ();
9. Computer newComputer= t.makeComputer();
10. System.out.println(“tempComputer所指向的对象可以被当作垃圾回收”);
11. Computer computer1=new Computer();
12. Computer computer2=new Computer();
13. computer2= computer1;
14. Computer computer3=new Computer();
15. computer3=null;
16. System.out.println(“computer3所指向的对象可以被当作垃圾回收”);
17. computer1=null;
18. System.out.println(“computer1所指向的对象不能被当作垃圾回收”);
19. }
20. }
当对象失去引用的情况下,可以被当作垃圾回收。
|
电脑2 |
computer2 |
应当指出的是,虽然可以通过将对象的引用变量初始化为null值来暗示垃圾收集线程收集该对象,但此时如果该对象连接有事件监听器,那它还是不可以被收集。所以在设一个引用变量为null值之前,应注意该引用变量指向的对象是否被监听,若有,要首先除去监听器,然后才可以赋空值。
三、对象离开作用域
我们知道,在传统的面向过程语言(如C语言)中,当一个方法执行完毕,其中的局部变量就因离开了作用域而被释放;以后当该方法再次被调用时,其中的局部变量会被重新创建。但在VB、C++等引入面向对象方法的编程语言中,其程序中基本类型的变量可以在离开作用域后被自动释放,但对象并不能被自动释放。JAVA语言的垃圾回收线程通过自动跟踪对象的使用情况,能够使程序中的对象类似于基本类型那样在离开作用域之后被回收。
基于例1中的第1行~第10行,可以分析一个JAVA对象如何因“离开作用域”而满足被回收的条件。
|
临时电脑 |
tempComputer |
第4行Computer tempComputer = new tempComputer();创建了引用(标签)tempComputer,及对应的对象(真实的电脑),可以形象地理解为把标签tempComputer贴在临时电脑上。
第9行,Computer newComputer= t.makeComputer();通过调用t的方法makeComputer()来创建一个Computer的对象,并用标签把newComputer贴在该电脑上。对象tempComputer是一个局部变量,在方法makeComputer结束后,系统会自动地把函数返回值作一份拷贝复制给调该方法的引用,然后对象tempComputer被当作垃圾回收。(有疑惑,个人用finalize()验证下来,该程序只有两个可回收的垃圾对象)
四、JAVA垃圾回收机制的特点
前面我们讨论了JAVA程序中的对象在什么条件下满足被回收的条件,而垃圾回收线程如何回收这些“垃圾”,则遵循以下两个特性。
1. 自动性。Java技术提供了一个系统级的线程,即垃圾收集器线程,来跟踪每一块分配出去的内存空间,当Java 虚拟机处于空闲循环时,垃圾收集器线程会自动检查每一块分配出去的内存空间,然后自动回收每一块可以回收的无用的内存块。
2. 不可预期性。一个对象成为了垃圾,但是你不能断言,该对象在这行以后就立刻被清除,甚至有可能当程序结束后,该对象仍然占用内存。像Windows这样的软件常常会出现内存不足的情况,JAVA程序很少出现就是因为可以自动回收内存。然而,因为JAVA也不能保证及时地清除无用的对象,所以JAVA程序也会出现内存不足的情况,只是这种情况很少出现。垃圾收集线程在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回收的,程序员也不能强制垃圾收集器回收该内存块。程序员唯一能做的就是通过调用System.gc 方法来"建议"执行垃圾收集器,但其是否可以执行,什么时候执行却都是不可知的。
最后
以上就是危机百褶裙为你收集整理的java垃圾回收的两个条件的全部内容,希望文章能够帮你解决java垃圾回收的两个条件所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复